You are here:

C++/C++ converting roman to decimal

Advertisement


Question
Hi i've been given a problem as follow

In Programming Exercise 1 in Chapter 11 (D.S. Malik, 4th edition), we defined a class romanType to implement Roman numbers in a program. In that exercise, we also implemented a function, romanToDecimal, to convert a Roman number into its equivalent decimal number.

Modify the definition of the class romanType so that the member variables are declared as protected.  Use the class newString, as designed in Programming Exercise 7 Chapter 14 (D.S. Malik, 4th edition), to manipulate strings.  Furthermore, overload the stream insertion and stream extraction operators for easy input and output.  The stream insertion operator outputs the Roman number in the Roman format.

Also, include a member function, decimalToRoman, that converts the decimal number (the decimal number must be a positive integer) to an equivalent Roman number format.  Write the definition of the member function decimalToRoman.

For simplicity, we assume that only the letter I can appear in front of another letter, and that it appears only in front of the letters V and X.  For example, 4 is represented as IV, 9 is represented as IX, 39 is represented as XXXIX, and 49 is represented as XXXXIX.  Also, 40 will be presented as XXXX, 190 will be represented as CLXXXX, and so on.

Here's my starting program :

#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

class romanType
{
     public:
         void storeNum (char Usernum[20]);
         void convertNum(int&);
         void print (int&) const;
     protected:
         char num [20];
};

int main()
{
   romanType myNum;
 int total;
   char Usernum[20];
   cout<<"Please enter roman numerals : ";
   cin.get(Usernum, 20);
   myNum.storeNum(Usernum);
   myNum.convertNum(total);
   myNum.print(total);
   system("pause");
   return 0;
}

void romanType::storeNum(char Usernum[20])
{
    for (int i =0; i<20; i++)
    num[i] = Usernum[i];
}
         
void romanType::convertNum(int &total)
{
    
    total = 0;
    int SIZE = strlen(num);
    int count[SIZE];
   
    for (int i = 0; i < SIZE ; i++)
    {
        switch(num[i])
         {
         case 'M':
         count[i] = 1000;
         break;
         case 'D':
         count[i] = 500;
         break;
         case 'C':
         count[i] = 100;
         break;
         case 'L':
         count[i] = 50;
         break;
         case 'X':
         count[i] = 10;
         break;
         case 'V':
         count[i] = 5;
         break;
         case 'I':
         count[i] = 1;
         break;
         }
         total = total + count[i];
         }
         
         for (int i = 0; i < SIZE-1; i++)
         {
         if(count[i] < count[i+1])
         total = total - 2 * count[i];
         }        
}         
    
void romanType::print(int& total)const
{
   cout<<"the answer is "<<total;
   cout<<endl;
}   

Please guide me through this programming problem. I've been thinking for a week with no avail. thanks

Answer
Rules regarding Roman numerals sometimes state that a symbol representing 10^n may not precede any symbol larger than 10^(n+1).
For example, C cannot be preceded by I or V, only by X (or, of course, by a symbol representing a value equal to or larger than C). Thus, one should represent the number ninety-nine as XCIX (using decimal places -- 90 (XC) then 9 (IX)), not as the "shortcut" IC.

Also, that no symbol representing a number equal to 5*10n where n is an integer (such as V, L, or D) can precede a symbol larger than it. For example 45 would be written as XLV instead of VL.

However, these rules are not universally followed. For example, you can see 1990 sometimes written as MXM (instead of MCMXC), and 1999 written as IMM or MIM (instead of MCMXCIX).

Assuming that the simpler set of rules hold, and 1990 can be written simply as MIM, the algorithm for converting a number from Roman Numerals to Decimal is easy:

Step 1. Set the value of the decimal value to zero.

Step 2. Check the string containing the Roman characters from left to right, keeping track of the values of the current and previous characters (use a switch as in your code):

    a. if  we reach the end of the string, add the value of the previous character to the decimal value. And we are done.
    
    b. if the value of the current character is greater than the value of the previous character, subtract the value of the previous character from the decimal value.

    b. if the value of the current character is less than or equal to the value of the previous character, add the value of the previous character from the decimal value.

void romanType::convertNum( int& total )
{
   const int SIZE = std::strlen(num);
   int count[SIZE] = { 0 } ;
  
   for( int i = 0 ; i < SIZE ; ++i )
   {
       switch( ::toupper( num[i] ) )
         {
         case 'M':
         count[i] = 1000;
         break;
         case 'D':
         count[i] = 500;
         break;
         case 'C':
         count[i] = 100;
         break;
         case 'L':
         count[i] = 50;
         break;
         case 'X':
         count[i] = 10;
         break;
         case 'V':
         count[i] = 5;
         break;
         case 'I':
         count[i] = 1;
         break;
         }
         }
         
         total = 0;

         for (int i = 1 ; i < SIZE ; ++i )
         {
         if( count[i] > count[i-1] )
         total -= count[i-1] ;
         else
         total += count[i-1] ;
         }

         total += count[ SIZE - 1 ] ;        
}  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.