Сравните значение enum - PullRequest
       7

Сравните значение enum

0 голосов
/ 13 сентября 2018

Реализация инфикс к калькулятору постфикса и необходимо проверить, если оператор имеет более низкий приоритет, чем другой. Вот что у меня есть:

public enum Operators {

    ADD('+', 2), SUBTRACT('-', 2), MULTIPLY('*', 4), DIVIDE('/', 4);

    private char operator;
    private int precedence;

    Operators(char operator, int precedence) {
        this.operator = operator;
        this.precedence = precedence;
    }

    public char getOperator() {
        return operator;
    }

    public int getPrecedence() {
        return precedence;
    }
}

private static boolean isOperator(char c) {
    return c == Operators.ADD.getOperator() || c == Operators.SUBTRACT.getOperator()
            || c == Operators.MULTIPLY.getOperator() || c == Operators.DIVIDE.getOperator();
}

private static boolean isLowerPrecedence(char ch1, char ch2) {
    // STUCK HERE
}

Я пробовал несколько разных вещей, чтобы проверить приоритетность передаваемого символа, но безрезультатно. Есть ли простой способ сравнить два значения перечисления? Должен ли я создать цикл?

Ответы [ 5 ]

0 голосов
/ 14 сентября 2018

Вы можете использовать EnumLookup вспомогательный класс, предложенный в этого моего ответа (исходный код EnumLookup там).

После повторного определения вашего Operators перечисления немного (янастоятельно рекомендуем использовать имя единственного класса), вы получите:

public enum Operator {

    ADD('+', 2), SUBTRACT('-', 2), MULTIPLY('*', 4), DIVIDE('/', 4);

    private static final EnumLookup<Operator, Character> BY_OPERATOR_CHAR
            = EnumLookup.of(Operator.class, Operator::getOperatorChar, "operator char");

    private final char operatorChar;
    private final int precedence;

    Operator(char operatorChar, int precedence) {
        this.operatorChar = operatorChar;
        this.precedence = precedence;
    }

    public char getOperatorChar() {
        return operatorChar;
    }

    public int getPrecedence() {
        return precedence;
    }

    public static EnumLookup<Operator, Character> byOperatorChar() {
        return BY_OPERATOR_CHAR;
    }
}

private static boolean isOperator(char c) {
    return Operator.byOperatorChar().contains(c);
}

private static boolean isLowerPrecedence(char ch1, char ch2) {
    return Operator.byOperatorChar().get(ch1).getPrecedence() < Operator.byOperatorChar().get(ch2).getPrecedence();
}

Основным недостатком этого подхода является то, что ваш char получает в штучной упаковке в Character, но если производительность некритично для вашего приложения, я бы об этом не беспокоился (удобочитаемость должна быть более важной).

0 голосов
/ 13 сентября 2018

Посмотрев на этот вопрос , вы сможете узнать, как Java обрабатывает сравнения типов через интерфейсы Comparable и Comparator .

Конечно, они предназначены для более сложных ситуаций, чем эта, но я думаю, вы должны принять их во внимание, чтобы вы могли увидеть правильный способ работы с набором алгоритмов упорядочения, предоставляемых стандартной библиотекой Java.

Поскольку вы не можете переопределить Enum по умолчанию compareTo (он объявлен как final ), вы можете реализовать свой собственный Comparator следующим образом:

public class OperatorsComparator implements Comparator<Operators> {

    @Override
    public int compare(Operators o1, Operators o2) {
        return o1.getPrecedence() - o2.getPrecedence();
    }
}

Тогда вам понадобится какой-то способ найти правильное Operators значение из char, которое вы даете:

private static Operators findOperator(char c){
    for(Operators op : Operators.values()){
        if(op.getOperator() == c)
            return op;
    }
    return null;
}

Используя вычитание между двумя предыдущими и предыдущими поисковыми системами Operators, вы можете реализовать свой isLowerPrecedence метод следующим образом:

public static boolean isLowerPrecedence(char c1, char c2) throws Exception {
    Operators o1 = findOperator(c1);
    Operators o2 = findOperator(c2);
    if(o1 == null || o2 == null)
        throw new Exception("Invalid operators");

    return new OperatorsComparator().compare(o1, o2) <= 0;
}

Сравнив таким образом приоритеты, вы получите, что o1 будет помечен как более низкий приоритет, даже если он имеет тот же приоритет, что и o2, как поведение по умолчанию. Остерегайтесь символов, которые вы пытаетесь использовать в качестве оператора, так как вам нужно поймать Exception, если что-то пойдет не так

Пример выполнения:

System.out.println(isLowerPrecedence('+', '-'));
System.out.println(isLowerPrecedence('+', '*'));
System.out.println(isLowerPrecedence('/', '-'));
System.out.println(isLowerPrecedence('/', '*'));
System.out.println(isLowerPrecedence('*', '-'));

печатает эти сообщения:

true
true
false
true
false
0 голосов
/ 13 сентября 2018

Или вы можете сравнить приоритет следующим образом:

private static boolean isLowerPrecedence(Operators operatorFirst, Operators operatorSecond) {
    if(operatorFirst.getPrecedence() < operatorSecond.getPrecedence()){
        return true;
    } else {
        return false;
    }
}

Конечно, это можно записать как:

return operatorFirst.getPrecedence() < operatorSecond.getPrecedence();
0 голосов
/ 13 сентября 2018

Вы можете циклически изменять значения enum для соответствия правильному оператору и сравнивать его приоритеты:

private static boolean isLowerPrecedence(char ch1, char ch2) {
    Integer first = null;
    Integer second = null;
    for (Operators o: Operators.values()) {
        if (o.getOperator() == ch1) {
            first = o.getPrecedence();
        }
        if (o.getOperator() == ch2) {
            second = o.getPrecedence();
        }
    }
    return (first != null && second !=null && first < second);
}

Возвращение boolean, когда оператор не был найден, может сбить с толку. Вместо этого я рекомендую бросить исключение в таком случае.

...
if (first == null || second ==null) throw new Exception("Operator not found.");
return first < second;
0 голосов
/ 13 сентября 2018

Это легко сравнить, если у вас есть метод, который переводит «оператор» char в значение перечисления.

Например:

static Operators getOperatorForChar(char op) {
    for(Operators val: values())
        if(op == val.operator)
            return val; //return enum type

    return null;
}

И тогда вы можете реализовать свойМетод с использованием:

private static boolean isLowerPrecedence(char ch1, char ch2) {

    //assuming intention is to compare precedence of ch1 to that of ch2
    return getOperatorForChar(ch1).precedence < getOperatorForChar(ch2).precedence;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...