4

Trying to write program to read in a string of characters that represent a Roman numeral (from user input) and then convert it to Arabic form (an integer). For instance, I = 1, V = 5, X = 10 etc.

Basically, the constructor that takes a parameter of type String must interpret the string (from user input) as a Roman numeral and convert it to the corresponding int value.

Is there an easier way to solve this besides the below in progress (which isn't compiling as yet):

import java.util.Scanner;

public class RomInt {
String roman;
int val;
void assign(String k)
{
  roman=k;
}

private class Literal
{
    public char literal;
    public int value;

    public Literal(char literal, int value)
    {
        this.literal = literal;
        this.value = value;
    }
}

private final Literal[] ROMAN_LITERALS = new Literal[]
        {
                new Literal('I', 1),
                new Literal('V', 5),
                new Literal('X', 10),
                new Literal('L', 50),
                new Literal('C', 100),
                new Literal('D', 500),
                new Literal('M', 1000)
        };

public int getVal(String s) {

   int holdValue=0;

        for (int j = 0; j < ROMAN_LITERALS.length; j++)
        {
            if (s.charAt(0)==ROMAN_LITERALS[j].literal)
            {
                       holdValue=ROMAN_LITERALS[j].value;
                           break;
            }  //if()
        }//for()

  return holdValue;
}  //getVal()
public int count()
{
   int count=0;
   int countA=0;
   int countB=0;
   int lastPosition = 0;
    for(int i = 0 ; i < roman.length(); i++)
    {
      String s1 = roman.substring(i,i+1);
        int a=getVal(s1);
        countA+=a;
    }
    for(int j=1;j<roman.length();j++)
    {
        String s2=  roman.substring(j,j+1);
        String s3=  roman.substring(j-1,j);
        int b=getVal(s2);
        int c=getVal(s3);
        if(b>c)
        {
            countB+=c;
        }
    }
    count=countA-(2*countB);
    return count;
    }


void disp()
{

     int result=count();
    System.out.println("Integer equivalent of "+roman+" = " +result);
}


  public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.print("Please enter Roman Symbol:");
String s = keyboard.nextLine();
RomInt();

}

}  
bmargulies
  • 97,814
  • 39
  • 186
  • 310
user3003605
  • 385
  • 4
  • 6
  • 13
  • 2
    This question is overly broad for Stack Overflow. Please keep working and ask us if you have a specific question. You might get more general input on Code Review, but you'll be more likely to get useful help if you describe your algorithm instead of pasting a big block of nonworking code. – chrylis -cautiouslyoptimistic- Dec 01 '13 at 14:39
  • do you just need the output of these numerals? Need to display them or need to use those converted arabic numerals for further use ? – Sameer Sawla Dec 01 '13 at 14:48
  • In the first glance you are not creating Object of RomInt class – Kishore Dec 01 '13 at 14:50

5 Answers5

10

Roman numerals/Decode Example:

class Roman {

    private static int decodeSingle(char letter) {
        switch (letter) {
            case 'M':
                return 1000;
            case 'D':
                return 500;
            case 'C':
                return 100;
            case 'L':
                return 50;
            case 'X':
                return 10;
            case 'V':
                return 5;
            case 'I':
                return 1;
            default:
                return 0;
        }
    }

    public static int decode(String roman) {
        int result = 0;
        String uRoman = roman.toUpperCase(); //case-insensitive
        for (int i = 0; i < uRoman.length() - 1; i++) {//loop over all but the last character
            if (decodeSingle(uRoman.charAt(i)) < decodeSingle(uRoman.charAt(i + 1))) {
                result -= decodeSingle(uRoman.charAt(i));
            } else {
                result += decodeSingle(uRoman.charAt(i));
            }
        }
        result += decodeSingle(uRoman.charAt(uRoman.length() - 1));
        return result;
    }

    public static void main(String[] args) {
        System.out.println(decode("MCMXC")); //1990
        System.out.println(decode("MMVIII")); //2008
        System.out.println(decode("MDCLXVI")); //1666
    }
}
Alya'a Gamal
  • 5,624
  • 19
  • 34
2

Use enum, for easy and simple solution. At first define the decimal equivalent weight at roman.

enum Roman{
    i(1),iv(4),v(5), ix(9), x(10);
    int weight;

    private Roman(int weight) {
        this.weight = weight;
    }
};

This is the method to convert decimal to roman String.

static String decToRoman(int dec){
    String roman="";
    Roman[] values=Roman.values();
    for (int i = values.length-1; i>=0; i--) {
       while(dec>=values[i].weight){
           roman+=values[i];
           dec=dec-values[i].weight;
       }            
    }
    return roman;
}
Masudul
  • 21,823
  • 5
  • 43
  • 58
0

You can try using a Hashmap to store the roman numerals and equivalent arabic numerals.

HashMap test = new HashMap();

test.add("I",1);
test.add("V",5);
test.add("X",10);
test.add("L",50);
test.add("C",100);
test.add("D",500);
test.add("M",1000);
//This would insert all the roman numerals as keys and their respective arabic numbers as 
  values.

To retrieve respective arabic numeral one the input of the user, you can use following peice of code:

Scanner sc = new Scanner(System.in);
System.out.println(one.get(sc.next().toUpperCase()));
//This would print the respective value of the selected key.This occurs in O(1) time.

Secondly,

If you only have these set of roman numerals, then you can go for simple switch case statement.

switch(sc.next().toUpperCase())
{
case 'I' :
     System.out.println("1");
     break;
case 'V'
     System.out.println("5");
     break;
.
.
.
& so on 
}

Hope this helps.

Sameer Sawla
  • 729
  • 6
  • 20
0

How about this:

public static int convertFromRoman(String roman) {
    Map<String, Integer> v = new HashMap<String, Integer>();
    v.put("IV", 4);
    v.put("IX", 9);
    v.put("XL", 40);
    v.put("CD", 400);
    v.put("CM", 900);
    v.put("C", 100);
    v.put("M", 1000);
    v.put("I", 1);
    v.put("V", 5); 
    v.put("X", 10);
    v.put("L", 50);
    v.put("D", 500);
    int result = 0;
    for (String s : v.keySet()) {
     result += countOccurrences(roman, s) * v.get(s);
     roman = roman.replaceAll(s, "");
    }

    return result;
}



public static int countOccurrences(String main, String sub) {
   return (main.length() - main.replace(sub, "").length()) / sub.length();
} 

Not sure I've got all possible combinations as I'm not an expert in roman numbers. Just make sure that the once where you substract come first in the map.

Blub
  • 3,762
  • 1
  • 13
  • 24
0

Your compilation issue can be resolved with below code. But surely its not optimized one:

public static void main(String[] args)
{
    Scanner keyboard = new Scanner(System.in);
    System.out.print("Please enter Roman Symbol:");
    String s = keyboard.nextLine();

    RomInt temp = new RomInt();
    temp.getVal(s);
    temp.assign(s);
    temp.disp();
}
Chris Forrence
  • 10,042
  • 11
  • 48
  • 64
Kishore
  • 300
  • 3
  • 14