Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Roman Numeral

Posted on 2005-04-04
6
Medium Priority
?
451 Views
Last Modified: 2010-04-01
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 answer;
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;
     }
       return answer;
}
0
Comment
Question by:Kal130
  • 4
  • 2
6 Comments
 
LVL 39

Expert Comment

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

int main()
{
    char YesNo;
    int answer;
    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

by:itsmeandnobodyelse
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.

Some comments:

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;
     }
     return answer;
}


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

by:Kal130
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

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

Expert Comment

by:itsmeandnobodyelse
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

Add

    #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

by:
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)  

  instead of

    if (duplicate > 2)

  to allow 4 occurences of C, X and I

- use

    if (duplicate > 3)  

  instead of

    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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
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.
Suggested Courses

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

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

Join & Ask a Question