
November 19th, 2011, 08:53 PM
#1
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
Not sure how to really begin going about this. Any ideas/help would be greatly appreciated!

November 19th, 2011, 09:51 PM
#2
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 romannumeral 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 romannumeral representation of this.number
}
}
Best Regards,
BioPhysEngr
http://blog.biophysengr.net

All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

November 19th, 2011, 10:40 PM
#3
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();
}
}
}
Best Regards,
BioPhysEngr
http://blog.biophysengr.net

All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

November 19th, 2011, 10:45 PM
#4
Re: Roman Numeral Calculator Help
Also here is some information regarding Infixtopostfix 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!
Best Regards,
BioPhysEngr
http://blog.biophysengr.net

All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

November 20th, 2011, 01:36 PM
#5
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...
Tags for this Thread
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

Click Here to Expand Forum to Full Width
OnDemand Webinars (sponsored)
