nartz
asked on
Roman Numeral Converter
here's a function for converting a Roman to an integer
int toDec( string roman )
{
int val=0;
map<char, int> valMap;
valMap['I']=1;
valMap['V']=5;
valMap['X']=10;
valMap['L']=50;
valMap['C']=100;
valMap['D']=500;
valMap['M']=1000;
string::iterator i=roman.begin();
while( i!=roman.end() )
{
int t=0;
string::iterator old=i;
for(; *i==*old && i!=roman.end(); i++ ) t+=valMap[*i];
if( valMap[ *i ] > valMap[ *old ] && i!=roman.end() ) val -= t;
else val += t;
}
return val;
}
int toDec( string roman )
{
int val=0;
map<char, int> valMap;
valMap['I']=1;
valMap['V']=5;
valMap['X']=10;
valMap['L']=50;
valMap['C']=100;
valMap['D']=500;
valMap['M']=1000;
string::iterator i=roman.begin();
while( i!=roman.end() )
{
int t=0;
string::iterator old=i;
for(; *i==*old && i!=roman.end(); i++ ) t+=valMap[*i];
if( valMap[ *i ] > valMap[ *old ] && i!=roman.end() ) val -= t;
else val += t;
}
return val;
}
I'v a question for the reverse
is XIVX == XVI? I suppose the latter is correct.
is XIVX == XVI? I suppose the latter is correct.
XVI==16
XIVX==No roman number,only I is allowed to the
left of higher signs(like IV,IX,...)not VX
XIVX==No roman number,only I is allowed to the
left of higher signs(like IV,IX,...)not VX
so you can write IV but not XL ?
To express XL you'd have to XXXX?
To express XL you'd have to XXXX?
on a sidemark, the romans where crazy, they used a number system on a nonregular-symetric base and a "depends" left/right write rule.
if one'v had to express their base i'd look like.
n%2 ? n^2 : n^5
Crazy!
if one'v had to express their base i'd look like.
n%2 ? n^2 : n^5
Crazy!
here's a function to generate Roman Numbers
string toRoman( unsigned int dec )
{
typedef list<int>::iterator lIter;
typedef string::iterator sIter;
map<int,char> cMap;
cMap[1]='I';
cMap[5]='V';
cMap[10]='X';
cMap[50]='L';
cMap[100]='C';
cMap[500]='D';
cMap[1000]='M';
list<int> nLst;
nLst.push_back( 1000 );
nLst.push_back( 500 );
nLst.push_back( 100 );
nLst.push_back( 50 );
nLst.push_back( 10 );
nLst.push_back( 5 );
nLst.push_back( 1 );
int div;
string result;
for( lIter i= nLst.begin(); i!=nLst.end(); i++ )
{
div = dec/(*i);
if( div!=4 || i==nLst.begin() )
result += string( div, cMap[*i] );
else if( div==4 )
{
lIter t=i; sIter cLast = result.end()-1;
--t;
if( *cLast == cMap[*t] )
{
*cLast = cMap[*--t];
result.insert( cLast, cMap[*i] );
}
else
{
result += cMap[*i];
result += cMap[*t];
}
}
dec %= *i;
}
return result;
}
The toDec and to toRoman functions are complementary, testing showed that for every case they match in results, thus the algorithm is correct.
string toRoman( unsigned int dec )
{
typedef list<int>::iterator lIter;
typedef string::iterator sIter;
map<int,char> cMap;
cMap[1]='I';
cMap[5]='V';
cMap[10]='X';
cMap[50]='L';
cMap[100]='C';
cMap[500]='D';
cMap[1000]='M';
list<int> nLst;
nLst.push_back( 1000 );
nLst.push_back( 500 );
nLst.push_back( 100 );
nLst.push_back( 50 );
nLst.push_back( 10 );
nLst.push_back( 5 );
nLst.push_back( 1 );
int div;
string result;
for( lIter i= nLst.begin(); i!=nLst.end(); i++ )
{
div = dec/(*i);
if( div!=4 || i==nLst.begin() )
result += string( div, cMap[*i] );
else if( div==4 )
{
lIter t=i; sIter cLast = result.end()-1;
--t;
if( *cLast == cMap[*t] )
{
*cLast = cMap[*--t];
result.insert( cLast, cMap[*i] );
}
else
{
result += cMap[*i];
result += cMap[*t];
}
}
dec %= *i;
}
return result;
}
The toDec and to toRoman functions are complementary, testing showed that for every case they match in results, thus the algorithm is correct.
nartz,
Is this a homework question?
If so, experts can assist in finding errors in code written, but not provide the whole code.
Please refrain from posting here until I get a response from nartz.
Computer101
E-E Admin
Is this a homework question?
If so, experts can assist in finding errors in code written, but not provide the whole code.
Please refrain from posting here until I get a response from nartz.
Computer101
E-E Admin
I'd think it's time to close this topic, since answers have been provided...
Recommending question be PAQ'ed and points NOT refunded. Any objections? If none in 72 hours I will close this.
DigitalXtreme
CS Moderator
DigitalXtreme
CS Moderator
ASKER
LOL, omg something was wrong with E-E that day! omg, I tried to post all my code and everything together, but for some reason when i tried to view my post, all it said was "no text" and i was like wtf! So then i tried to repost it and it still didnt' work (losing muchos puntos in the process) and the code didn't get attached but somehow it just posted the comment, i finish the proggie...oh well =)
Nartz
Nartz
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
nartz, instead of omging and loling around you either should have posted your solution or promoted an answer!
#include <conio.h>;
#include <ctype.h>;
#include <stdio.h>;
#include <dos.h>;
int main (void) {
int numR = 0; /* Decimal value of roman numeral */
int decR = 0; /* Decimal value of each roman numeral */
int cont = 0; /* String position */
int cont3R = 0; /* 3 incurs counter */
int numsR[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/* Array that store the value of each
roman letter */
char letterR = ' '; /* Contain the temporal roman letter */
char roman[15] = ""; /* Contain the input string */
/* Clear the screen and display the input message */
clrscr();
printf ("Enter a roman numeral between range I to MMMCMXCIX:\n");
/* Read from keyboard until appear an <ENTER> */
while ((letterR != '\n') && (cont < 15)) {
letterR = toupper(getchar());
switch (letterR) {
/* V, L y D only can appear one time */
case 'V': case 'L': case 'D':
/* If appear more of one time, then finish the program */
if ((cont > 0) && (roman[cont - 1] == letterR)) {
printf ("\nData incorrect");
delay (1000);
exit (0);
}
/* If appear one time, be save the char in the string that
store the characters of roman numeral */
else { roman[cont++] = letterR; }
break;
/* I, X, C y M can appear until 3 times */
case 'I': case 'X': case 'C': case 'M':
/* If appear correctly, be save the char in the string that
that store the characters of roman numeral */
if (cont3R <= 3) {
roman[cont++] = letterR;
}
cont3R++;
/* If appear more of 3 times, then finish the program */
if ((cont3R > 3) && (roman[cont - 2] == letterR)) {
printf ("\nData incorrect");
delay (1000);
exit (0);
}
/* If the 3 incurs counter get to be 3 but the preceding char
is different of current, then reset the 3 incurs counter */
if ((cont > 1) && ((cont3R > 3) || (roman[cont - 2] != letterR))) {
cont3R = 1;
}
break;
/* Invalidate the \n char as default char */
case '\n': break;
/* If the input is a char that not concern to roman numerals,
then finish the program */
default: printf ("\nData incorrect");
delay (1000);
exit (0);
}
}
/* Reutilization of cont3R var as index of iterations for no create
a new var and then optimize the program */
/* Convert to decimal each letter of roman numeral that was input */
for (cont3R = 0; cont3R <= cont; cont3R++) {
switch (roman[cont3R]) {
case 'I': numsR[cont3R] = 1; break;
case 'V': numsR[cont3R] = 5; break;
case 'X': numsR[cont3R] = 10; break;
case 'L': numsR[cont3R] = 50; break;
case 'C': numsR[cont3R] = 100; break;
case 'D': numsR[cont3R] = 500; break;
case 'M': numsR[cont3R] = 1000; break;
}
}
/* Do a sum over stored numbers */
for (cont3R = 0; cont3R <= cont; cont3R++) {
/* */
/* Add decimal value of each roman numeral */
if (numsR[cont3R] >= numsR[cont3R + 1]) {
decR = numsR[cont3R];
}
/* If precedent number is less than current value and this is 10%
or 5% of current value, then do a difference between two roman
numerals to obtain the final value i.e. IX = 10 - 1 = 9 */
if ((numsR[cont3R] == (numsR[cont3R + 1] / 10))
|| (numsR[cont3R] == (numsR[cont3R + 1] / 5))) {
decR = numsR[cont3R + 1] - numsR[cont3R];
cont3R++;
}
/* If precedent numbre is less than current value and not is 10% or
5% of current value, then finish the program */
if (decR < numsR[cont3R + 1]) {
printf ("\nData incorrect");
delay (1000);
exit (0);
}
numR += decR;
}
/* Diplay result in the screen */
printf ("The value is %d", numR);
/* Press any key to finish the program */
printf ("\n\n\t\t\t...Press any key to exit.");
getch();
/* Return succesfully */
return 0;
}