将罗马数字转换为阿拉伯语

时间:2015-10-08 02:36:08

标签: java roman-numerals

我是Java的新手,我需要编写一个将罗马数字转换为阿拉伯数字的程序。

我不能使用某些功能,因为我不允许更改给定代码的结尾。我需要在public static void main函数中执行所有操作。

我开始在Google上搜索并开始编码。从现在开始,我只能转换一个字母"数字(如X,I,V ......)与阿拉伯数字相比,但我不能做到超过精心设计的数字(XI,CCC,IX,IV ......)。

有人能帮助我吗?我是Java的新手。这是我的第一个程序语言,我很难理解它。

这是我的代码:

import java.util.Scanner;

class Roman {

    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);
        int[] numbers = {1000, 500, 100, 50, 10, 5, 1 };
        String symbols = "MDCLXVI";

        /*******************************************
         * Complete your program
         *******************************************/

        System.out.print("Enter a roman numeral");
         final int MAX = 3999;
            Scanner keyb = new Scanner(System.in);
            String roman = keyb.next();
            roman=roman.toUpperCase();

            if(roman.matches(".*[0-9].*") || !roman.matches("[M|D|C|L|X|V|I]*")){
                System.out.println("Impossible to convert. Wrong roman numeral");
            } 

            int i = 0; //position in the string romain
            int arabic = 0; // Arabic numeral equivalent of the part of the string that
                            // has been converted so far


            int number;
            while (i < roman.length()){

                char letter = roman.charAt(i); // letter at the current position in the string


                if (letter == 'I'){
                    number = 1;
                } else if (letter == 'V'){
                    number = 5;
                } else if (letter == 'X'){
                    number = 10;
                } else if (letter == 'L'){
                    number = 50;
                } else if (letter == 'C'){
                    number = 100;
                } else if (letter == 'D'){
                    number = 500;
                } else if (letter == 'M'){
                    number = 1000;
                } else {
                    number = -1;
                }

                i++; // Move on to next position in the string

                if (i==roman.length()){
                    // There is no letter in the string following the one we have just processed.
                    // So just add the number corresponding to the single letter to arabic.

                    arabic += number;

                } else {
                    // Look at the next letter in the string.  If it has a larger Roman numeral
                    // equivalent than number, then the two letters are counted together as
                    // a Roman numeral with value (nextNumber - number).


                    number = roman.charAt(i);
                    int nextNumber = number;
                    if(nextNumber > number){
                        // Combine the two letters to get one value, and move on to next position in string.
                        arabic += (nextNumber - number);
                        i++;

                    } else {
                        // Don't combine the letters.  Just add the value of the one letter onto the number.
                        arabic += number;

                    }
                }
                System.out.println(number);
            } // end while

        /*******************************************
         * Do not change after this line.
         *******************************************/
    }
}

2 个答案:

答案 0 :(得分:2)

我建议您使用枚举来表示您的罗马数字。这使得代码很好地封装了。

public enum Roman {
    I(1), V(5), X(10), L(50), C(100), D(500), M(1000);
    private final int value;
    private Roman(int value) {
        this.value = value;
    }
    public int toInt() {
        return value;
    }
}

将单个罗马数字转换为整数变得微不足道。例如:

Roman.valueOf("X").toInt();

唯一复杂的一点是应对“IX”和“XC”类型的值。识别这些的简单方法是,它们是数字不按值降序排列的唯一时间。检查这个可以作为enum本身的方法添加(继续封装):

public enum Roman {
    public boolean shouldCombine(Roman next) {
        return this.value < next.value;
    }
    public int toInt(Roman next) {
        return next.value - this.value;
    }
}

现在把它们放在一起:

List<Roman> romans = new ArrayList<>();
input.chars().mapToObj(Character::valueOf)
    .map(Roman::valueOf).forEach(romans::add);
int value = 0;
while (!romans.isEmpty()) {
    Roman current = romans.remove(0);
    if (!romans.isEmpty() && current.shouldCombine(romans.get(0))
        value += current.toInt(romans.remove(0));
    else
        value += current.ToInt();
}

此代码的第一部分使用Java 8功能将字符串转换为罗马数字。如果您发现令人困惑,请告诉我,我会将其转换为传统迭代。

答案 1 :(得分:0)

这是形式语言中的“一个展望”。解决此问题的唯一方法是将位置0与下一个char进行比较。如果value小于,则从acccumulator中减去值,如果&gt; =,则添加。