2012-03-23 6 views
0

Для моей программы мне нужно генерировать действительные выражения infix с настраиваемой сложностью. Проблема в том, что я не могу найти способ предотвратить деление на ноль, ответы с плавающей запятой и отрицательные ответы.Произвольно генерировать действительное арифметическое выражение infix

Чтобы предотвратить отрицательные ответы, я принимаю грязный подход. То есть, генерировать выражение, оценить его, если он оказывается отрицательным, генерировать again.Here некоторые вещи, которые вы должны знать:

  1. inToPost() представляет собой метод, который преобразует сгенерированное выражение инфиксную в постфикса для оценка.
  2. complexLevel < = DIVIDE подразумевает, что мы не должны помещать скобки в выражение.
  3. complexLevel == ARITHMETIC_PARENTHESIS подразумевает, что скобки включены.

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

public void generateRandom(int operandLimit, int operatorCount, int complexityLevel) { 
     Random rand = new Random(); 
     infix.clear(); 

     int i = 0; 
     infix.add(rand.nextInt(operandLimit) + 1); 

     while(i < operatorCount) { 
      int operator; 
      if(complexityLevel <= DIVIDE) 
       operator = rand.nextInt(complexityLevel - 1)*1000 + 1000; 
      else 
       operator = rand.nextInt(complexityLevel - 3)*1000 + 1000; 

      int operand = rand.nextInt(operandLimit) + 1; 

      if(operator == Operator.DIVIDE) { 
       int lastNum = infix.get(infix.size() - 1); 

       if(lastNum < operand) { 
        int temp = operand; 
        operand = lastNum; 
        lastNum = temp; 
       } 

       lastNum -= lastNum % operand; 
       infix.set(infix.size() - 1, lastNum); 
      } 

      infix.add(operator); 
      infix.add(operand); 

      ++i; 
     } 

     if(complexityLevel == ARITMETIC_PARENTHESIS) { 
      int braceOpen = rand.nextInt(operatorCount) * 2; 
      infix.add(braceOpen, Operator.BR_OPEN); 
      infix.add(braceOpen + 4, Operator.BR_CLOSE); 
     } 

     inToPost(); 
     if(evaluate() < 0) 
      generateRandom(operandLimit, operatorCount, complexityLevel); 
    } 

ответ

0

похоже, что вы имели дело с вашими условиями (б) и (в) уже. Поскольку ваши операнды никогда не равны 0, я бы предположил, что единственное возможное нарушение (a) заключается в том, что добавленные скобки завершают нулевое значение, а оператор до этого является делением. Вы можете проверить для этого случая, если вы редактировали inToPost() принять подвыражения:

if(braceOpen > 0 && infix.get(braceOpen) == Operator.DIVISION && 
     evaluate(inToPost(infix.subList(braceOpen, braceOpen + 3))) == 0) { 
    // Put parentheses elsewhere, or cancel 
} 
+0

Я мог бы изменить оператор внутри от - до + для этого. Спасибо :) – wirate

+0

для C) Я действительно не чувствую, что я делаю это правильно. Генерирование выражений снова и снова до тех пор, пока не появится ответ + – wirate

+0

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