Переключение оператора с использованием подстроки ввода пользователя - PullRequest
0 голосов
/ 28 мая 2019

Цель: Я пытаюсь вывести сообщение на основе ввода пользователя.

Ситуация: Обычно пользователь вводит несколько символов, таких как 5r (5 красных) или 8y (8 желтых). Ожидаемая запись - сначала цифра, а затем символ, но возможно, что пользователь не следует правилу.

Я использовал операторы switch (часть упражнения), но результат не дает того, что я ожидаю

код

        String input = reader.nextLine().toLowerCase();
        String firstChar = input.substring(0,1);
        String secondChar = input.substring(1);
        String answer = "";

        switch(firstChar)
        {
            case "0":
            {
                switch(secondChar)
                {
                    case "b":
                        answer = "Zero Blue";
                    case "r":
                        answer = "Zero Red";
                    case "g":
                        answer = "Zero Green";
                    case "y":
                        answer = "Zero Yellow";
                }
            }
            case "1":
            {
                switch(secondChar)
                {
                    case "b":
                        answer = "One Blue";
                    case "r":
                        answer = "One Red";
                    case "g":
                        answer = "One Green";
                    case "y":
                        answer = "One Yellow";
                }
            }
           ... other case statements....
           default:
              answer = "not valid";

Когда пользователь пишет 0b, мой вывод должен быть «Zero Blue», но в настоящее время он отображает «not valid». Почему?

Ответы [ 2 ]

1 голос
/ 28 мая 2019

Я предлагаю вообще не использовать swich case, используйте хеш-карты:

package mypackage;

import java.util.*;

public class MyComputingClass {

    private static Map<Character, String> firstCharMapping;
    private static Map<Character, String> secondCharMapping;

    public static void main(String[] args) {
        initCharMappers();

        System.out.println("Mapping of 0Y : " + mapStuff("0Y"));
        System.out.println("Mapping of 0y : " + mapStuff("0y"));
        System.out.println("Mapping of 0YJ : " + mapStuff("0YJ"));
        System.out.println("Mapping of 2B : " + mapStuff("2B"));
        System.out.println("Mapping of eB : " + mapStuff("eB"));
    }

    private static void initCharMappers() {
        firstCharMapping = new HashMap<>();
        secondCharMapping = new TreeMap<>(Comparator.comparing(Character::toLowerCase));

        firstCharMapping.put('0', "Zero");
        firstCharMapping.put('1', "One");
        firstCharMapping.put('2', "Two");

        secondCharMapping.put('Y', "Yellow");
        secondCharMapping.put('B', "Blue");
        secondCharMapping.put('G', "Green");
    }

    private static String mapStuff(String str) {
        String INVALID_INPUT = "Invalid input";
        if (!str.matches("\\d[a-zA-Z]")) {
            return INVALID_INPUT;
        }

        Character firstChar = str.toCharArray()[0];
        Character secondChar = str.toCharArray()[1];

        if (!firstCharMapping.containsKey(firstChar) || !secondCharMapping.containsKey(secondChar)) {
            return INVALID_INPUT;
        }

        return firstCharMapping.get(firstChar) + " " + secondCharMapping.get(secondChar);
    }
}

Выход:

Mapping of 0Y : Zero Yellow
Mapping of 0y : Zero Yellow
Mapping of 0YJ : Invalid input
Mapping of 2B : Two Blue
Mapping of eB : Invalid input
1 голос
/ 28 мая 2019

Как уже упоминалось в @markspace, вы пропустили оператор break. Вот краткий отрывок из документации Java по операторам переключения:

Каждый оператор break завершает вмещающий оператор switch. Поток управления продолжается с первого оператора, следующего за блоком переключателей. Операторы break необходимы, потому что без них операторы в блоках переключателей не работают.

Также я рекомендую использовать специальный метод и циклы for для упрощения отладки.

Следующий код дает желаемый результат:

public static String getAnswer() {

        Scanner reader = new Scanner(System.in);
        String input = reader.nextLine().toLowerCase();
        String firstChar = input.substring(0, 1);
        String secondChar = input.substring(1);

        String[] chars = new String[] { "b", "r", "g", "y" };
        String[] answers1 = new String[] { "Zero Blue", "Zero Red", "Zero Green", "Zero Yellow" };
        String[] answers2 = new String[] { "One Blue", "One Red", "One Green", "One Yellow" };

        if ((firstChar.equals("0"))) {
            for (int i = 0; i < chars.length; i++) {
                if (secondChar.equals(chars[i])) {
                    return answers1[i];
                }
            }
        }
        else if ((firstChar.equals("1"))) {
            for (int i = 0; i < chars.length; i++) {
                if (secondChar.equals(chars[i])) {
                    return answers2[i];
                }
            }
        }
        return "not valid";
    }

    public static void main(String[] args) throws IOException {

        System.out.println(getAnswer());
    }

РЕДАКТИРОВАТЬ: В дополнение к решению, приведенному выше, я хотел бы предложить более сложный, который предполагает использование перечислителей. Это должно сделать ваш код более понятным и конкретным, а также более модульным:

public enum Answer {

    BLUE('b',"Blue"), RED('r',"Red"),
    GREEN('g',"Green"), YELLOW('y',"Yellow");

    private static final String[] prefix = new String[] {"Zero", "One"};

    char letter;
    String name;

    Answer(char letter, String name) {
        this.letter = letter;
        this.name = name;
    }

    public static String getForInput(char input, int index) {

        if (index > prefix.length)
            return "value out of range " + index;

        for (Answer answer : Answer.values()) {
            if (input == answer.letter)
                return prefix[index] + " " + answer.name;
        }
        return "unable to find answer for input " + input;
    }
}

public static String getAnswer() {

    System.out.println("Enter your input: ");
    Scanner reader = new Scanner(System.in);
    String input = reader.nextLine().toLowerCase();
    int number = Integer.valueOf(input.substring(0, 1));
    char letter = input.substring(1).charAt(0);

    return Answer.getForInput(letter, number);

}
...