# Roman Numeral Calculator Help

• November 19th, 2011, 07:53 PM
Legax
Roman Numeral Calculator Help
I am tyring to create a Roman Numeral Calculator in C#. I want this calculator to accept two numbers (in Roman Numeral form) and then allow a single mathematical operation to be performed (+, -, *, /).

Using Roman Numerals:

I=1, V=5, X=10, L=50, C=100, D=500, M=1000

I want this to prompt for the first operand (rom1), operator(+, -, *, /), second operand (rom2) and then display results.

Ex. rom1 op rom2 = sol

Input Operand 1: XXV
Input Operator: -
Input Operand 2: V

Result: XX

• November 19th, 2011, 08:51 PM
BioPhysEngr
Re: Roman Numeral Calculator Help
I'd write a Roman Numeral class that (a) accepts a string in the constructor, (b) internally represents the number as an int, (c) has an add method, and (d) has a method to convert an int to roman numerals.

Code:

```class RomanNumeral {     public int number;     //Constructors     public RomanNumeral(int number)          { this.number = number; }     public RomanNumeral(string numString)    { this.number = parseString(numString); }     private static int parseString(string s) {         //Parse a roman-numeral string to an int     }         //Add two roman numerals     public static RomanNumeral add(RomanNumeral x, RomanNumeral y) {         return new RomanNumeral(x.number + y.number);     }     //Overload the + operator     public overload RomanNumeral operator+(RomanNumeral x, RomanNumeral y) {         return add(x,y);     }     public string getRomanNumeralString() {         //Return a string containing a roman-numeral representation of this.number     } }```
• November 19th, 2011, 09:40 PM
BioPhysEngr
Re: Roman Numeral Calculator Help
So, there apparently is a project euler problem about roman numerals and - since I find those fun anyway - I worked out the algorithms.

The algorithm for representing a number in Roman Numeral form is:

Create a list of all possible roman numeral "digits" (which includes I, V, X, L, C, D, M and the digraphs IV, IX, XL, XC, CD, CM with values 1, 5, 10, 50, 100, 500, 1000, and 4, 9, 40, 90, 400, 900, respectively). At each step, choose the "digit" with a value closest - without going over - to the remainder. Namely:

Code:

```resultString = ""; while number > 0 do     resultString = resultString + highestDigitWithoutGoingOver;     number = number - valueOfLastDigitAdded; loop```
---

Similarly, to "read" a roman numeral string just scan from left to right. First check if any of the digraphs (IV, IX, ...) match at the current location. If so, add their value to your resulting int. Otherwise, check the single character digits (I, V, X...)

--

Hopefully that should be clear. If not here is my source code (in C#) to do parsing:

Code:

```using System; namespace PE89 {         class Program         {                 static string[] glyphs = { "I", "IV", "V", "IX", "X", "XL", "L",  "XC", "C", "CD", "D", "CM", "M" };                 static int[] values = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };                                                 public static void Main(string[] args)                 {                         //Console.WriteLine(parseRN("MCMXCVI"));                         //Console.WriteLine(toRN(parseRN("MCMXCVI")));                                                 string[] lines = System.IO.File.ReadAllLines("roman.txt");                                                 int savings = 0;                         foreach(string line in lines)                         {                                 string bestRep = toRN(parseRN(line));                                                                 savings += (line.Length - bestRep.Length);                         }                                                 Console.WriteLine(savings);                                                 Console.Write("Press any key to continue . . . ");                         Console.ReadKey(true);                 }                                 public static int parseRN(string rn)                 {                         int result = 0;                         int ptr = 0;                         while( ptr < rn.Length )                         {                                 int nextIndex = longestMatchingGlyphIndex(rn, ptr);                                                                 result += values[nextIndex];                                 ptr += glyphs[nextIndex].Length;                         }                                                 return result;                 }                                 public static int longestMatchingGlyphIndex(string rn, int ptr)                 {                         int longest = -1;                         int index = -1;                                                 for(int i = 0; i < glyphs.Length; i++)                         {                                 if( ptr + glyphs[i].Length > rn.Length )                                         continue;                                                                 if( glyphs[i].Length >= longest && rn.Substring(ptr, glyphs[i].Length) == glyphs[i] )                                 {                                         longest = glyphs[i].Length;                                         index = i;                                 }                         }                                                 return index;                 }                                 public static string toRN(int number)                 {                         System.Text.StringBuilder result = new System.Text.StringBuilder();                         while( number > 0 )                         {                                 int index = highestGlyphWithoutExceeding(number);                                 result.Append(glyphs[index]);                                 number -= values[index];                         }                                                 return result.ToString();                 }                                 public static int highestGlyphWithoutExceeding(int number)                 {                         for(int i = glyphs.Length - 1; i>= 0; i--)                         {                                 if( values[i] <= number )                                         return i;                         }                                                 throw new ArgumentException();                 }         } }```
• November 19th, 2011, 09:45 PM
BioPhysEngr
Re: Roman Numeral Calculator Help
Also here is some information regarding Infix-to-postfix notation conversion: https://en.wikipedia.org/wiki/Shunting_yard_algorithm

You may find it easier to evaluate infix expressions if you first convert them to postfix (RPN). That link might help.

Good luck!
• November 20th, 2011, 12:36 PM
HanneSThEGreaT
Re: Roman Numeral Calculator Help
Can I add a spanner in the works here....

What about fractions, in other words the duodecimal system? The reaosn why I feel to mention this is because this system is a bit different than ours...