-
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 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
}
}
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 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!
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
|