Solved

# Roman Numeral

Posted on 2005-04-04
Medium Priority
444 Views
i have a source code, so far i have whats listed below...i have 2 questions: the first is, for some reason and i cant figure out why, but when i run the program once, it works fine, but once i try to repeat it, it stores the answer in the first input and calculates the total w/ the 2nd.  Also, i also need it to convert the numbers back into roman numerals and im unsure of how i could do this...i cant use pointers and nothing too 'advanced'...any help would be greatly appreciated.

this is my source code:

#include <iostream>
#include <cmath>
#include <string>
using namespace std;

void Roman (int&);
int Operation (int, int, char);

char YesNo;
int first;
int second;
int amount;
char Number;

int main()

{
do{
{

amount = 0;

cout<<"Enter the first roman numeral"<<endl;
Roman(first);
cout<<"Enter the second roman numeral"<<endl;
Roman(second);
cout<<"Enter the (+) for Addition (-) for Subtraction, (*) for Multiplication, or (/) for Division"<<endl;
cin.get(Number);
Operation (first, second, Number);
cout<<first<<" "<<Number<<" "<<second<<" is "<<Operation(first,second,Number)<<"."<<endl;

cout << "Do you want to Repeat Process Y or N" << endl;
cin >> YesNo;
}
}      while ((YesNo =='y' || YesNo =='Y'));
return 0;
}

void Roman (int& amount)
{
char RN;
cin.get(RN);

while (RN != '\n')
{

if (RN == 'M')
amount = amount + 1000;
if (RN == 'D')
amount = amount + 500;
if (RN == 'C')
amount = amount + 100;
if (RN == 'L')
amount = amount + 50;
if (RN == 'X')
amount = amount + 10;
if (RN == 'V')
amount = amount + 5;
if (RN == 'I')
amount = amount + 1;
cin.get(RN);
}

}
int Operation (int first, int second, char Number)
{
if (Number == '+')
{
answer  = first + second;
}
if (Number == '-')
{
answer  = first - second;
}
if (Number == '*')
{
answer  = first * second;
}
}
0
Question by:Kal130
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• Learn & ask questions
• 4
• 2

LVL 39

Expert Comment

ID: 13704821
You should  avoid to use global variables but move them to the function where you need them.

int main()
{
char YesNo;
int first;
int second;

do
{
...

>>>> void Roman (int& amount)

Better is

int Roman()

where you would return the value entered by the user.

Note, you used 'int amount' as global variable and as an argument, what is bad (but isn't an error as the latter was used). The reason, why your variable increases in the second run is cause you never initialize it to 0.

int Roman ()
{
int amount = 0;  // make a local variable *but* remove the global one
char RN;
cin.get(RN);

while (RN != '\n')
{
switch(RN)
{
case 'M':
amount = amount + 1000; break;
case 'C'':
amount = amount + 100; break;
case 'L':
amount = amount + 50; break;
case 'X':
amount = amount + 10; break;
case 'V':
amount = amount + 5; break;
case 'I':
amount = amount + 1; break;
default:
return -1;         // bad value
}
}
return amount;
}

Note, you didn't consider the case where numbers have to be subtracted rather than added as in IX == 9. Your result would be 11.

Regards, Alex
0

LVL 39

Expert Comment

ID: 13708714
To build (and parse) roman numbers (M, D, C, L, X, V, I) you have to apply the following rules:

1. The composite number is build up in thousands, hundreds, tens and ones from left to right.
2. To build 900, 400, 90, 40, 9, 4 you have to precede the next number by one single
C (M and D), X (C and L) or I (X and V).
3. You have to take the minimum notation if there are more than one possible

Samples:

99     == XCIX (90 + 9) and not LXXXXVIIII (breaks rule 3) or IC (breaks rule 2) or LIL (breaks rule 2).
2321 == MMCCCXXI and not  MDDCCDXXI (MDD breaks rule 3) (CCD  breaks rule 1 and rule 2)

Here is an attempt to consider these rules in function Roman.

I changed char input to char array input in order to be able to peek to the next char. Tell me, if you would be allowed to use std::string instead of char array.

I also moved user input to main function as Roman function should be free of I/O stuff (cause you could use it generally for transforming a Roman number to an integer).

Regards, Alex

int Roman ()
{
int amount = 0;  // make a local variable *but* remove the global one
char input[256];

cin >> input;
if (stricmp(input, "Q") == 0)
return 0;

char RP  = ' ';     // previous
char RN  = '\0';    // current
char RNN = '\0';    // next

int expected  = 1000;
int duplicate = 0;
for (int i = 0; i < strlen(input); ++i)
{
RP  = RN;
RN  = input[i];
RNN = input[i+1];
if (RP == RN)
duplicate++;
else
duplicate = 0;
switch(RN)
{
case 'M':
if (expected < 1000)
return -2;
amount += 1000;
break;
case 'D':
if (expected < 500)
return -2;
if (duplicate)
return -3;
amount += 500;
expected = 100;
break;
case 'C':
if (expected < 100)
return -2;
if (duplicate > 2)
return -3;
if (duplicate == 0 && (RNN == 'M' || RNN == 'D'))
{
amount += (RNN == 'M')? 900 : 400;
expected = 50;
i++;
}
else
amount += 100;
if (expected > 100)
expected = 100;
break;
case 'L':
if (expected < 50)
return -2;
if (duplicate)
return -3;
amount += 50;
expected = 10;
break;
case 'X':
if (expected < 10)
return -2;
if (duplicate > 2)
return -3;
if (duplicate == 0 && (RNN == 'L' || RNN == 'C'))
{
amount += (RNN == 'C')? 90 : 40;
expected = 5;
i++;
}
else
amount += 10;
if (expected > 10)
expected = 10;
break;
case 'V':
if (expected < 5)
return -2;
if (duplicate)
return -3;
amount += 5;
expected = 1;
break;
break;
case 'I':
if (expected < 1)
return -2;
if (duplicate > 2)
return -3;
if (duplicate == 0 && (RNN == 'V' || RNN == 'X'))
{
amount += (RNN == 'X')? 9 : 4;
expected = 0;
i++;
}
else
amount += 1;
if (expected > 1)
expected = 1;
break;
default:
return -1;         // bad value
}
}
return amount;
}

int Operation (int first, int second, char Number)
{
int answer = -1;
if (Number == '+')
{
answer  = first + second;
}
if (Number == '-')
{
answer  = first - second;
}
if (Number == '*')
{
answer  = first * second;
}
}

int main()
{
char input[256];
int first, second, result;
while (true)
{
cout << "First Roman  [Q to quit] ==>  ";
cin >> input;
if (stricmp(input, "Q") == 0)
return 0;

first = Roman(input);
cout << endl << "First = " << first << endl << endl;
if (first <= 0)
continue;

cout << "Second Roman [Q to quit] ==>  ";
cin >> input;
if (stricmp(input, "Q") == 0)
return 0;

second = Roman(input);
cout << endl << "Second = " << second << endl << endl;

if (second <= 0)
continue;
cout<<"(+) Addition \n(-) Subtraction \n(*) Multiplication \n(/) Division \n(Q) Quit \n\nEnter Choice ==> ";
cin >> input;

if (stricmp(input, "Q") == 0)
return 0;

result = Operation(first, second, input[0]);
cout << endl << "result = " << result << endl << endl;
}
return 0;
}

0

Author Comment

ID: 13708759
hey im sorry to note, that i dont have to put 4 like IV, it have to be IIII
same w/ the rest of them
0

Author Comment

ID: 13708822
std:: string i tink would be better because we havent gotten in depth w/ char array
0

LVL 39

Expert Comment

ID: 13709265
>>>> hey im sorry to note, that i dont have to put 4 like IV, it have to be IIII

Are you crazy? It costs me hours to correctly parse the input and you say, it's all for nothing?

Actually IIII is an invalid number and you would get error -2 if entering it.

>>>> std:: string i tink would be better

#include <string>
using namespace std;

to the top of your cpp file.

Change the first part of Roman function to

int Roman (const string& input)
{
int amount = 0;  // make a local variable *but* remove the global one
char RP  = ' ';     // previous
char RN  = '\0';    // current
char RNN = '\0';    // next

int expected  = 1000;
int duplicate = 0;
for (int i = 0; i < input.length(); ++i)
{
RP  = RN;
RN  = input[i];
RNN = input.c_str()[i+1];  // input[i+1] isn't valid for std::string
// if i+1 == input.length()
...
// remainder didn't change

Change main function to

int main()
{
string input;
int first, second, result;
while (true)
{
cout << "First Roman  [Q to quit] ==>  ";
cin >> input;
if (input == "Q" || input == "q")
return 0;

first = Roman(input);
cout << endl << "First = " << first << endl << endl;
if (first <= 0)
continue;

cout << "Second Roman [Q to quit] ==>  ";
cin >> input;
if (input == "Q" || input == "q")
return 0;

second = Roman(input);
cout << endl << "Second = " << second << endl << endl;

if (second <= 0)
continue;
cout<<"(+) Addition \n(-) Subtraction \n(*) Multiplication \n(/) Division \n(Q) Quit \n\nEnter Choice ==> ";
cin >> input;

if (input == "Q" || input == "q")
return 0;

result = Operation(first, second, input[0]);
cout << endl << "result = " << result << endl << endl;
}
}

Regards, Alex
0

LVL 39

Accepted Solution

itsmeandnobodyelse earned 2000 total points
ID: 13709369
>>>> that i dont have to put 4 like IV, it have to be IIII

If you really need a wrong parsing, you have to

- remove all lines and if blocks using RNN variable

- use

if (duplicate > 3)

if (duplicate > 2)

to allow 4 occurences of C, X and I

- use

if (duplicate > 3)

if (duplicate)

to allow 4 occurences of D, L and V

- remove all lines and if blocks using 'expected' variable if you want to allow any order

- remove all lines and if blocks using 'duplicate' variable if you want to allow any number of repetitions

(But save the original if you do any of this. As it is the correct version!!!)

Regards, Alex
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more â€¦
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilationâ€¦
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
###### Suggested Courses
Course of the Month14 days, 9 hours left to enroll

#### 771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.