C++ converting base 10 to Roman numerals

  • Thread starter Thread starter Math Is Hard
  • Start date Start date
  • Tags Tags
    Base C++
AI Thread Summary
The discussion centers on converting base 10 numbers to Roman numerals using C++. The original poster struggles with implementing a loop to handle the conversion efficiently without using arrays, as they are not yet familiar with that concept. Suggestions include using functions to encapsulate repeated logic and considering a while loop for subtraction instead of division for better efficiency. Participants also discuss the importance of maintaining the correct order of Roman numeral symbols during conversion and share various coding approaches, emphasizing clarity and elegance in the code. Ultimately, the conversation highlights the challenges and strategies involved in programming this conversion task effectively.
  • #51
Oh, I didn't see you had posted--took me a while to do that translation. 1 moment.

Edit: Okay, you raise a valid point. I will think about how best to modify my method to do 9's, 90s, and 900s correctly. It will still be very short though.
 
Last edited:
Physics news on Phys.org
  • #52
Alright, let me have a shot at this:

Code:
#include <iostream>
#include <cstdio>

using namespace std;

int main(int argc, char **argv)         {
	int *input = new int();
	int *rom = new int[7];
	int *steps = new int[6];
	char *map = new char[7];
	*map = 'M'; *(map+1)='D'; *(map+2)='C'; *(map+3)='L'; *(map+4)='X';
	*(map+5)='V'; *(map+6)='I';

	printf("Please enter the number that must be converted: ");
	scanf("%i", input);
	
	*rom = *input / 1000;
	*(rom + 1) = (*steps = *input % 1000) / 500;
	*(rom + 2) = (*(steps+1) = *steps % 500) / 100;
	*(rom + 3) = (*(steps+2) = *(steps+1) % 100) / 50;
	*(rom + 4) = (*(steps+3) = *(steps+2) % 50) / 10;
	*(rom + 5) = (*(steps+4) = *(steps+3) % 10) / 5;
	*(rom + 6) = (*(steps+4) % 5);
	
	printf("Here is your number in Roman numerals: ");
	for (register int i = 0; i < 6; i++) {
		for (register int k = 0; k < *(rom + i); k++) printf("%c", *(map + i));
	};

	switch(*(rom+6))	{
		case 1: printf("%s", "I"); break;
		case 2: printf("%s", "II"); break;
		case 3: printf("%s", "III"); break;
		case 4: printf("%s", "IV"); break;
		default: break;	};

	return 0;				}

Please compile Multi-threaded! :biggrin:

PS: Don't be hatin' on the printf! :smile:
 
Last edited by a moderator:
  • #53
Interesting, but not correct:

Please enter the number that must be converted: 1999
Here is your number in Roman numerals: MDCCCCLXXXXVIV

3 errors: DCCCC for 900, LXXXX for 90, VIV for 9


Edit: What's the "multithreaded" comment about?
 
  • #54
Ah crap, didn't notice that. Awesome beta testing on your part.

I meant, if your compiler supports it (I think all compilers nowadays do), like gcc 3.4.x, compile it for Multi-threaded mode (to support Intel Hyper-Threading!) and notice the performance difference. I believe the code is significantly faster if it runs multithreaded.


Btw, I found this rather succint piece of code (I'm quite sure it works) http://home.att.net/~srschmitt/script_roman.html . I feel a JScript to C/C++ conversion is in order. :-p
 
Last edited by a moderator:
  • #55
freemind said:
Btw, I found this rather succint piece of code (I'm quite sure it works) http://home.att.net/~srschmitt/script_roman.html . I feel a JScript to C/C++ conversion is in order. :-p
That's no good -- it's not obfuscated at all! :-p :-p

Here's my latest effort. It's not as short as I'd hoped it would be, but I think it's cute:
Code:
#include <iostream>
#include <string>
#include <math.h>
using namespace std;         // added this line for MSVC 6.0
#define LTRS "MDCLXVI"
int iter[]={9,5,4};
void build(int& val, int p, string& s){
    int r = (int)pow(10,p);
    while(val>=r){
        val -= r;
    s += LTRS[6-2*p];
    }
}
void trim(string t, int i, int j, string &s){
    int ind = s.find(t,0);
    string tt;
    if (j!=1)
        tt += LTRS[2*i+2];
    j == 0 ? tt += LTRS[2*i] : tt += LTRS[2*i+1];
    if (ind >=0)
       s.replace(ind, iter[j], tt);
}
int main(){
    int i, j, k, p, dec;
        string t, roman;
    cout << "Enter integer to be translated:\n";
    cin >> dec;
    for(p = 3; p >=0; p--)
        build(dec, p, roman);
    for(i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            t.erase();
            for(k = 0; k < iter[j]; k++)
                t += LTRS[2*i+2];
            trim(t,i,j,roman);
        }
    }
    cout << roman.c_str() << endl;            // edited for MSVC 6.0
    return 0;
}
 
Last edited by a moderator:
  • #56
I kinda half-understand your algorithm (it's very complex), but compiling it on Microsoft Visual C++ 7.0 and running in debug mode gives garbled output.
Did it give the correct lettering on your system?

P.S: AFAIK, the string class doesn't have operator overloading support for << (@ least not in the MSVC++ 7.0 implementation), which means 'cout << roman << endl;' threw tantrums. I had to change that to 'printf("%s", &roman);', but I doubt that's the cause of the messed result.
 
  • #57
Sorry, it worked fine in my old Dev-C++ (mingw compiler).

It also works fine in with my g++ compiler, but for that one I had to add "using namespace std;" so I edited my previous post to add that line.

I also made a small change to that final cout so now it compiles and runs correctly in MSVC 6. I don't know about MSVC 7.

Funny thing is, I have MSVC7 (I think). A few months ago I bought a student copy of Visual Studio .net but never used it. So now I'm trying, and DAMN if I can't figure out how to compile ANYTHING with it. So far all I seem to have here is the world's most complicated editor. There's buttons for everything under the sun, but no "compile", no "build", no "run". How the heck do I get this thing to do something useful?
 
Last edited:
  • #58
It works perfectly now!

I know what you mean. MSVC++.NET isn't exactly a quick-and-dirty superfast development IDE. But for large programs that use a lot of custom-built libraries, it is priceless. As for the compile, build and run buttons, it is quite silly that they don't exist in the default view. I simply use the shortcut Ctrl+Shift+B to build, and F5 to run (debug). Still, having used Borland C++ , Dev-C++ (it took forever to compile, I don't know why), and gcc/g++, I would still say that Microsoft makes the best compilers/IDEs around. Then again, I'm also known to be a M$-fanboy. :smile:

Kudos to gnome for a fine piece of code!
 
  • #59
Okay, here is my masterpiece!

Code:
#include <iostream>
int main(){
	string s = "IIIVIXXXLXCCCDCMMM";
	int n, c[] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
	cin>>n;
	for(int i=12; i>-1;n%=c[i], i--)
		cout<<(n/c[i]>0?s.substr(i+(i+3)/4,i%4?(i-2)%4?2:1:n/c[i]):"");
}
:smile: :smile: Hopefully I translated this into C++ right; it does work in Java. If you can't get it to work I'll post the Java code which is a little longer.
 
Last edited:
  • #60
Beautiful. I changed it slightly, adding "#include<string>", changed "String" to "string", and "cin >> n"; instead of your constant n.
Code:
#include <iostream>
#include <string>
int main(){
	string s = "IIIVIXXXLXCCCDCMMM";
	int n, c[] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
	cin >> n;
	for(int i=12; i>-1;n%=c[i], i--)
		cout<< (n/c[i]>0 ? s.substr(i+(i+3)/4, i%4 ? (i-2)%4 ? 2 : 1 : n/c[i]) : "");
}

edit: Oh, I see you already made two of those changes.

(But what if I have more than 3999 olives to count?) :-p


I've never seen a compound conditional statement like that. Is is just composed from the inside out, i.e.:
n/c>0 ? ([/color] s.substr(i+(i+3)/4, [[/color] i%4 ? [ (i-2)%4 ? 2 : 1] : n/c ][/color] ) )[/color] : ""
 
Last edited:
  • #61
If you want to count more than 3999, you would use parentheses around letters as explained at http://mathworld.wolfram.com/RomanNumerals.html. You wouldn't write MMMM. 4000 would be written M(V)

Edit: Or you could add a vinculum by using 2 lines of output and an underscore.

If for some reason you want to use more than 3 M's, you can just add more M's at the end of string s.

Yes, that's how the conditional statement works.
 
Last edited:

Similar threads

Replies
22
Views
3K
Replies
3
Views
1K
Replies
3
Views
3K
Replies
3
Views
2K
Replies
10
Views
2K
Replies
2
Views
1K
Replies
3
Views
1K
Replies
15
Views
12K
Back
Top