0

New programming student over here. Trying to convert a roman numeral input to it's integer value. I have been using this post over here as a guide. Here's the thing, I haven't learned about hashtables or enums so I can't use that in my code. Let me show you what I have so far:

    public static String romanInput(int number) {

    Scanner numberInput = new Scanner (System.in);
    System.out.print("Enter a roman numeral in uppercase: ");
    String userInput = numberInput.next();

    return userInput;
}

public static int numberConversion(String romanNumeral) {

    int result = 0;

    for (int x = romanNumeral.length() - 1; x >= 0 ; x--) {
        char romanConvert = romanNumeral.charAt(x);

        switch (romanConvert) {
            case 'I':
                result += 1;
                break;
            case 'V':
                result += 5;
                break;
            case 'X':
                result += 10;
                break;
            case 'L':
                result += 50;
            case 'C':
                result += 100;
                break;
            case 'D':
                result += 500;
                break;
            case 'M':
                result += 1000;
                break;
        }
    }
    return result;
}

public static int numberOutputs(String input, int converted) {

    String input = romanInput(output);
    int 
}



public static void main(String[] args) {



}

}

I haven't even gotten to the point where I can test this out, but I know what I am doing is wrong. I know that if the roman numerals entered are in decreasing value or in equal value, then you will add the values together. I know that if the number is less than the number that follows it, you wold subtract it's value. So I'm guessing the algorithm would be something like:

if (first number >= second number) {
    return (first number + second number)
} else {
    return (second number - first number) };

Is that what my conversion algorithm should look like?

Let me give you some more detail on what my assignment states: This program must have 3 methods and a main method!

  1. Write a method that takes input from the user and passes it to a conversion method.
  2. Write a method that yields the numeric value of each of the letters (conversion method).
  3. Write a method that outputs the number the user entered and the converted number.
  4. Write a main method to test the 3 methods.
    HINT: Use a single dimensional array!

So once I figure out how to write the algorithm, I then need to construct a method that outputs the number the user entered and the converted number. Would that just be something like:

System.out.println("The number you entered was: " +romanInput(input));

and then do the same for the converted roman numeral. What am I supposed to return in that method?

I don't want to just copy over what is over at the other post because I'm trying to understand how this program is supposed to work. This is an online course, so unfortunately I only have a book as a guide for this assignment so I would really appreciate help from a more experienced programmer.

Community
  • 1
  • 1
NEPat10
  • 159
  • 1
  • 2
  • 12
  • please refer http://stackoverflow.com/questions/23357394/disable-browsers-back-button-if-the-session-is-invalidated – sasmit Nov 09 '14 at 18:51

4 Answers4

1

This is obviously not a complete solution to your problem, but here's a general algorithm.

  1. Consider creating a map to hold keys (Roman numerals) and values (Arabic numerals).
  2. Parse the Roman numeral left to right.
  3. For each Roman numeral digit, inspect the Roman numeral digit to the right.
  4. If it's smaller you're done (fetch the Arabic number value for the Roman numeral in hand and add it to the result).
  5. If it's equal or larger, inspect the Roman numeral digit to the right.
  6. Repeat 4 and 5 until you reach the end.

I'm sure I missed something but this should give you a good starting point.

Can anyone think of a negative test that breaks this algorithm?

UPDATE

As I thought more about this, it seemed like a very nice compact problem for a quick job interview elimination round. A candidate should be able to write pseudo-code in 5 minutes and a working program in 20 minutes. So, I thought I'd create a reference implementation. So, here it is if you want to try it out on the web: My Roman to Arabic Converter

And here's the source for it. The logic of interest is in the convertRomanToArabic JavaScript function near the bottom. The rest is just boilerplate and harness.

I made it so it's all in one file. Save it to a file called index.html (or whatever you like) and open it in a browser. Let me know if you find any bugs or have any ideas for enhancements.

<!doctype html>
<html>
<head>
    <title>Roman To Arabic Converter</title>
    <!--
    <link rel="stylesheet" href="roman.css" type="text/css" media="screen">
    -->
    <style>
        body { width:900px; margin:auto; height:100%; overflow:hidden;  background-color:#eee; font-size:125%; }
        #label-input { font-size: 1.2em; font-style: bold; }
        #label-note { font-size: .9em; font-style: italic; } 
        #label-roman, #label-arabic { color:blue; }
    </style>
</head>
<body>
    <header>
        <!-- Always use a CDN, unless your network blocks it. -->
        <!--
        <script type="text/javascript"
            src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
        </script>

        <!-- Use a local library if your network doesn't let you get to a CDN. -->
        <!--
        <script type="text/javascript"
            src="js/lib/jquery-2.1.1.min.js">
        </script>
        -->
    </header>
    <p>
    <label id="label-input">Enter a Roman numeral below and press ENTER to convert it to an Arabic numeral</label>
    <br>
    <input type="text" id="roman-input"></input>
    <p>
    Roman:
    <label id="label-roman"></label>
    <p>
    Arabic:
    <label id="label-arabic"></label>
    <p>
    <label id="label-note">Note: I don't stop you from entering invalid Roman numerals, e.g. IXX, and they don't evaluate correctly.</label>
    <script>
        var
            convertRomanToArabic,
            Roman,
            Arabic,
            Map,
            MapList,
            RomanFragment,
            init;

        $("#roman-input").on("keypress", function(event){
            if (event.keyCode === 13) {
                convertRomanToArabic();
                $("#roman-input").focus();
                window.setTimeout(function(){
                    $('#inputTodo').focus();
                }, 50);
            }
        });

        init = function() {
                $("#roman-input").focus();
                window.setTimeout(function(){
                    $('#inputTodo').focus();
                }, 50);         
        }();

        convertRomanToArabic = function() {
            var x,
                fragment;

            Map = {};
            Map['I'] = 1;
            Map['V'] = 5;
            Map['X'] = 10;          
            Map['L'] = 50;
            Map['C'] = 100;
            Map['D'] = 500;
            Map['M'] = 1000;
            Arabic = 0;
            RomanFragment = "";
            Roman = $("#roman-input").val().toUpperCase();
            $("#label-roman").text(Roman);
            for (x=0; x < Roman.length-1; x++) {
                if (Map[Roman.substr(x+1,1)] <= Map[Roman.substr(x,1)]) {
                    if (RomanFragment !== "") {
                        Arabic -= Map[RomanFragment];
                        RomanFragment = "";
                    };
                    Arabic += Map[Roman.substr(x,1)];
                } else {
                    RomanFragment += Roman.substr(x,1);
                };
            };
            if (RomanFragment !== "") {
                Arabic -= Map[RomanFragment];           
                RomanFragment = "";
            };
            Arabic += Map[Roman.substr(Roman.length-1)];
            $("#label-arabic").text(Arabic);
        };
    </script>
</body>
</html>
Puneet Lamba
  • 755
  • 8
  • 15
0

Could maybe be this? =)

public class TEST
{
public int romanInput() {       
    return convert(getUserInput());
}   
public String getUserInput()
{
    Scanner numberInput = new Scanner (System.in);
    System.out.print("Enter a roman numeral in uppercase: ");
    String userInput = numberInput.next();
    numberInput.close();
    return userInput;
}   
public int convert(String userInput)
{
    int result = 0;
    for (int x = userInput.length() - 1; x >= 0 ; x--) {
        char romanConvert = userInput.charAt(x);
        switch (romanConvert) {
            case 'I':
                result += 1;
                break;
            case 'V':
                result += 5;
                break;
            case 'X':
                result += 10;
                break;
            case 'L':
                result += 50;
            case 'C':
                result += 100;
                break;
            case 'D':
                result += 500;
                break;
            case 'M':
                result += 1000;
                break;
        }
    }
    return result;
}

public void printValue()
{
    System.out.println(romanInput());
}

public static void main(String[] args) {
    new TEST().printValue();
}
}
Andrea Bori
  • 190
  • 2
  • 15
  • This is close. It just adds up all of the roman numerals and prints out the value. How would I fix it so that it subtracts if a number is less than a number that follows it? – NEPat10 Nov 09 '14 at 18:59
0

Unfortunately, to do this you need to go from right-to-left, as that's how Roman Numerals work. For instance, IXC is 100 - 10 - 1, not 100 - (10 - 1). To do this I would suggest something like this:

int result = 0;
int subtractamount = 0;
int x = userInput.length();
while(x != 0) {
char romanConvert = userInput.charAt(x);
    if(x >= 1) {
        if(convertChar(romanConvert) >= convertChar(userInput.charAt(x - 1)) {
            subtractamount += convertChar(userInput.charAt(x - 1))
        }
    }
    result += convertChar(romanconvert);
    x--;
}
result -= subtractamount;
return result;

Add a new method for repetition's sake:

public static char convertChar(char value) {
    switch (value) {
        case 'I':
            return 1;
            break;
        case 'V':
            return 5;
            break;
        case 'X':
            return 10;
            break;
        case 'L':
            return 50;
        case 'C':
            return 100;
            break;
        case 'D':
            return 500;
            break;
        case 'M':
            return 1000;
            break;
        default:
            System.out.println("Invalid character!");
            return 0;
            break;
    }

}

How it works: The while loop courses through right to left, and questions if there is a number beforehand that is less than or equal to the character being converted. If it is, it adds that numbers amount to the amount to be subtracted. Then, it adds the character being converted's value to the result. When finished, it subtracts the given amount from the result, giving the proper right-to-left result. I added that other method because I didn't want to repeat it each time.

mirvine
  • 126
  • 1
  • 2
  • 14
  • Sorry, I don't believe IXC is a valid Roman numeral. http://en.wikipedia.org/wiki/Roman_numerals http://literacy.kent.edu/Minigrants/Cinci/romanchart.htm – Puneet Lamba Nov 09 '14 at 23:11
  • I either misunderstood the question or the downvoter misunderstood the question, because this worked for me. Also, Roman numerals are very flexible. It's like math; there are an infinite of ways to come up with 10 (e.g. 5 + 5, 2 * 5, 4 - -6) but they all mean the same thing. – mirvine Nov 10 '14 at 21:42
  • Thank you my friend. I really appreciated you explaining to me how it works. I would like to keep it within the same method though. – NEPat10 Nov 11 '14 at 18:21
  • @NEPat10 You can keep it in the same method, but then you have to type the `swtich (...) case...break;` every time you convert the number. – mirvine Nov 13 '14 at 15:38
0

Assuming valid input, traversing the roman numeral from right to left can be done one char at a time, but you'll need to remember the previous char (char to the right of the cur char), so that you can subtract the value of cur_char if it's less than prev_char. Otherwise, you just add up char values from right to left.

I've seen a number of other ways as well which seem perfectly valid.