找到你要的答案

Q:Converting roman numerals to arabic

Q:罗马数字转换为阿拉伯语

I'm new to Java and I need to write a program that converts roman numerals to arabic numbers.

I cannot use some functions because I'm not allowed to change the begging neither the end of the given code. I need to do everything inside the the public static void main function.

I started to search on Google and started to code. From now, I can convert only "one-letter" numerals (as X, I, V...) to arabic numbers but I cannot do this to more than elaborated numerals (XI, CCC, IX, IV...).

Can someone help me? I'm really new to Java. It's my first program language and I'm struggling to understand it.

Here is my code:

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.
         *******************************************/
    }
}

我是新来的java,我需要写一个程序,将罗马数字为阿拉伯数字。

我不能使用一些函数,因为我不允许更改乞讨,也不是给定代码的结尾。我需要做的一切里面的公共静态空隙的主要功能。

我开始在谷歌上搜索并开始编写代码。从现在开始,我只能转换“一信”数字(X,I,V)对阿拉伯数字但我不能这样做,超过了数字(西、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.
         *******************************************/
    }
}
answer1: 回答1:

I would suggest using an enumeration for your individual roman numerals. That makes the code nicely encapsulated.

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

Converting a single roman numeral to an integer becomes trivial. For example:

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

The only complex bit is coping with "IX" and "XC" type of values. The easy way to identify these is that they are the only time when the numerals are not in descending order of value. Checking for this can be added as methods to the enum itself (to continue encapsulation):

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

Now putting it all together:

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();
}

The first part of this code uses Java 8 features to convert the string to roman numerals. Let me know if you find that confusing and I'll convert it to traditional iteration.

我建议使用一个枚举为您个人罗马数字。这使得代码很好地封装了。

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();

唯一复杂点是应对“九”和“越野”式的价值观。识别这些方法的简单方法是,它们是数字不按降序排列的唯一时间。检查这可以添加方法枚举本身(继续封装):

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将字符串转换为罗马数字特征。让我知道,如果你觉得混乱,我将它转换为传统的迭代。

answer2: 回答2:

Here is one way to do it:

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();
        keyb.close(); // don't want a resource leak

        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 Roman string

        int current = 0; // the current Roman numeral character to Arabic
                         // conversion

        int previous = 0; // start previous at zero, that way when
                          // current is greater than previous in the first
                          // run, nothing will be subtracted from current

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

        while (i < roman.length()) {

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

            // switch statement is easier to read than if - else if - else
            switch (letter) {
            case ('I'):
                current = 1;
                break;
            case ('V'):
                current = 5;
                break;
            case ('X'):
                current = 10;
                break;
            case ('L'):
                current = 50;
                break;
            case ('C'):
                current = 100;
                break;
            case ('D'):
                current = 500;
                break;
            case ('M'):
                current = 1000;
                break;
            }


            if (current > previous) {
                // subtract previous * 2 because previous was added to arabic
                // once already
                arabic += current - (previous * 2);
            } else {
                // if current is less than or equal to previous then add it to
                // arabic
                arabic += current;
            }

            previous = current; // set previous equal to current to check
                                // for less-than on next iteration

            i += 1; // move on to next position in the string

        } // end while

        // print the Arabic conversion after the loop is done
        System.out.println("Arabic: " + arabic);

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

In your code, the conditionals after i++ are not necessary since the while(i < roman.length()) conditional stops the loop once i >= roman.length().

Yet another way to do it: switch out the while loop with a for loop and a nested for loop. The outer for loop iterates over each character in the Roman numeral string. The inner for loop iterates over each character in the symbols string. If there is a match between the Roman numeral character and the symbols character, then current is set to the corresponding index in numbers and the inner loop breaks.

for(int i = 0; i < roman.length(); i++) {
    for(int s = 0; s < symbols.length(); s++) {
        if(roman.charAt(i) == symbols.charAt(s)) {
            current = numbers[s];
            break;
        }
    }

    if (current > previous) {
        // subtract previous * 2 because previous was added to arabic
        // once already
        arabic += current - (previous * 2);
    } else {
        // if current is less than or equal to previous then add it to
        // arabic
        arabic += current;
    }

    previous = current; // set previous equal to current to check
                        // for less-than on next iteration
}

这是一种方法:

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();
        keyb.close(); // don't want a resource leak

        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 Roman string

        int current = 0; // the current Roman numeral character to Arabic
                         // conversion

        int previous = 0; // start previous at zero, that way when
                          // current is greater than previous in the first
                          // run, nothing will be subtracted from current

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

        while (i < roman.length()) {

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

            // switch statement is easier to read than if - else if - else
            switch (letter) {
            case ('I'):
                current = 1;
                break;
            case ('V'):
                current = 5;
                break;
            case ('X'):
                current = 10;
                break;
            case ('L'):
                current = 50;
                break;
            case ('C'):
                current = 100;
                break;
            case ('D'):
                current = 500;
                break;
            case ('M'):
                current = 1000;
                break;
            }


            if (current > previous) {
                // subtract previous * 2 because previous was added to arabic
                // once already
                arabic += current - (previous * 2);
            } else {
                // if current is less than or equal to previous then add it to
                // arabic
                arabic += current;
            }

            previous = current; // set previous equal to current to check
                                // for less-than on next iteration

            i += 1; // move on to next position in the string

        } // end while

        // print the Arabic conversion after the loop is done
        System.out.println("Arabic: " + arabic);

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

在你的代码,经过我的+ +的条件是不必要的,因为(我& lt;罗马。length())条件停止循环一次我>;= length()罗马。

另一种方法是:用while循环和嵌套循环来切换while循环。外循环遍历在罗马数字字符串中的每个字符。内循环遍历各个字符的符号。如果罗马数字字符和符号字符之间有匹配,则将当前数字设置为相应的数字,内部循环断开。

for(int i = 0; i < roman.length(); i++) {
    for(int s = 0; s < symbols.length(); s++) {
        if(roman.charAt(i) == symbols.charAt(s)) {
            current = numbers[s];
            break;
        }
    }

    if (current > previous) {
        // subtract previous * 2 because previous was added to arabic
        // once already
        arabic += current - (previous * 2);
    } else {
        // if current is less than or equal to previous then add it to
        // arabic
        arabic += current;
    }

    previous = current; // set previous equal to current to check
                        // for less-than on next iteration
}
java  roman-numerals