Математические операторы - PullRequest
3 голосов
/ 04 марта 2012

У меня есть метод, который сгенерирует случайное математическое выражение, решит его и выведет ответ в переменную:

public int Nov2()
{
    char[] ops = new char[] {'+', '-', '*', '/'};
    int i = rand.nextInt(4-0) + 0;
    char op1 = ops[i];

    int novnum1 = rand.nextInt(101-1) + 1;

    int novnum2 = rand.nextInt(101-1) + 1;

    int nov2result = 0;

    switch(op1) {
        case '+': nov2result = novnum1 + novnum2; break;
        case '-': nov2result = novnum1 - novnum2; break;
        case '*': nov2result = novnum1 * novnum2; break;
        case '/': nov2result = novnum1 / novnum2; break;
    }

    String nov2Exp = novnum1 + " " + op1 + " " + novnum2 + " = ";

    Nov2resstor = nov2result;

    setContentView(R.layout.gameview);

    TextView display = (TextView) findViewById(R.id.exp);

    display.setText(nov2Exp);

    return nov2result;
}

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

public int Eas3()
{
    char[] ops = new char[] {'+', '-', '*', '/'};
    int i = rand.nextInt(4-0) + 0;
    char op1 = ops[i];
    i = rand.nextInt(4-0) + 0;
    char op2 = ops[i];

    int easnum1 = rand.nextInt(101-1) + 1;

    int easnum2 = rand.nextInt(101-1) + 1;

    int easnum3 = rand.nextInt(101-1) + 1;

    int eas3result = 0;


    if (op1 == '+' && op2 == '+')
    {
        eas3result = ((easnum1 + easnum2) + easnum3);
    }
    else if (op1 == '+' && op2 == '-')
    {
        eas3result = ((easnum1 + easnum2) - easnum3);
    }
    else if (op1 == '+' && op2 == '*')
    {
        eas3result = ((easnum1 + easnum2) * easnum3);
    }
    else if (op1 == '+' && op2 == '-')
    {
        eas3result = ((easnum1 + easnum2) - easnum3);
    } 
.../

У меня есть методы, которые делают это для 2,3,4,5 и 6, поэтому мои операторы if станут очень большими при использовании этого метода.

Есть идеи?

Ответы [ 9 ]

2 голосов
/ 04 марта 2012

Проверьте этот класс MathEval, который я нашел в Интернете Он оценит строку, представляющую уравнение для вас.

mySolver = new MathEval();
double answer = mySolver.evaluate(equation);
2 голосов
/ 04 марта 2012

Вы можете использовать встроенный движок Javascript.

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

public class Test 
{
  public static void main(String[] args) throws Exception
  {
       ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");
        String foo = "40+2";
        System.out.println(engine.eval(foo));
    } 
}
2 голосов
/ 04 марта 2012

Да, еще один способ сделать это - написать объекты Command:

public interface Command<V> {
    V execute(Object ... args); 
}

Вы напишите объект, который реализует этот интерфейс:

public class AdditionCommand implements Command<Double> {
    public Double execute(Object ... args) {
        Double x = (Double)args[0];
        Double y = (Double)args[1];
        return x+y;    
    }
}

Теперь вы можете искатьна карте с помощью оператора:

Map<String, Command> opsLookup = new HashMap<String, Command>() {{
   opsLookup.put("+", new AddCommand<Number>());
   opsLookup.put("-", new SubtractCommand<Number>());
}};

Нет необходимости в переключателе.

1 голос
/ 04 марта 2012

Как насчет использования рекурсии:

int num(int numberOfOperands, int current){
    if(numberOfOperands<=0) return current;
    switch(rand.nextInt(4)){
        case 0: return num(numberOfOperands-1, current + (rand.nextInt(100)+1)); break;
        case 1: return num(numberOfOperands-1, current - (rand.nextInt(100)+1)); break;
        case 2: return num(numberOfOperands-1, current * (rand.nextInt(100)+1)); break;
        case 3: return num(numberOfOperands-1, current / (rand.nextInt(100)+1)); break;
    }

}

int num(int numberOfOperands) throws Exception{
    if(numberOfOperands <=0) 
        throw new Exception("invalid number of operands: "+numberOfOperands);
    return num(numberOfOperands, rand.nextInt(100)+1);
}

Это, конечно, игнорирует приоритет операций.

1 голос
/ 04 марта 2012

То, что вы ищете, называется составной шаблон . Вы определяете абстрактный Expression базовый класс и выводите его.

Классы должны реализовывать метод evaluate(), который возвращает результат.

Один подкласс будет константой, возвращающей его значение, другой - двоичным выражением, таким как плюс, минус и т. Д. Метод evaluate() добавит / вычтет / и т.д. результат вычисленных подвыражений.

Затем вы можете строить произвольные выражения из других выражений и затем оценивать их, не используя одно условие if.

0 голосов
/ 10 ноября 2015

Попробуйте это:

public int Eas3()
{

    char[] ops = new char[] {'+', '-', '*', '/'};
    int i = rand.nextInt(4-0) + 0;
    char op1 = ops[i];
    i = rand.nextInt(4-0) + 0;
    char op2 = ops[i];

    int easnum1 = rand.nextInt(101-1) + 1;
    int easnum2 = rand.nextInt(101-1) + 1;
    int easnum3 = rand.nextInt(101-1) + 1;
    int eas3result = 0;
    if (op1 == '+')
    {
         switch(op2) 
         {
               case '+': eas3result=((easnum1 + easnum2) + easnum3); break;
               case '-': eas3result=((easnum1 - easnum2) - easnum3); break;
               case '*': eas3result=((easnum1 * easnum2) * easnum3); break;
               case '/': eas3result=((easnum1 / easnum2) / easnum3); break;        
         }
    }

..../

}

или даже вы можете поместить внешний IF в ПЕРЕКЛЮЧАТЕЛЬ, как показано ниже

public int Eas3()
{

    char[] ops = new char[] {'+', '-', '*', '/'};
    int i = rand.nextInt(4-0) + 0;
    char op1 = ops[i];
    i = rand.nextInt(4-0) + 0;
    char op2 = ops[i];

    int easnum1 = rand.nextInt(101-1) + 1;
    int easnum2 = rand.nextInt(101-1) + 1;
    int easnum3 = rand.nextInt(101-1) + 1;
    int eas3result = 0;
    int tempResult=0;
    switch(op1)
    {
         case '+': tempResult=(easnum1 + easnum2); break;
         case '-': tempResult=(easnum1 + easnum2) ; break;
         case '*': tempResult=(easnum1 + easnum2) ; break;
         case '/': tempResult=(easnum1 + easnum2) ; break;        
    }    
   switch(op2) 
     {
         case '+': eas3result=(tempResult + easnum3); break;
         case '-': eas3result=(tempResult - easnum3); break;
         case '*': eas3result=(tempResult * easnum3); break;
         case '/': eas3result=(tempResult / easnum3); break;        
     }

}

0 голосов
/ 04 марта 2012

Если у вас есть n операций с n + 1 числами, и вы делаете первое, то у вас остается n-1 операции с n номерами.Вы можете использовать это как основу для цикла, который будет легко обрабатывать любое количество элементов.

int operate(int[] numbers, int[] operations) {
  if (numbers.length < 1 || numbers.length != operations.length + 1) {
    throw new IllegalArgumentException();
  }
  int result = numbers[0];  
  for (int i = 0; i < operations.length; ++i) {
    result = operate(operations[i], result, numbers[i+1]);
    // where operate() is your switch statement
  }
  return result;
}
0 голосов
/ 04 марта 2012

Я бы использовал массив для значений easnum [], массив для операндов op [] и массив с промежуточными значениями.Что-то вроде следующего

  for(...)
  {
     if(op[i]=='+') easintermediat[i+1] = easintermediate[i] + easnum[i]
     ...
  }
0 голосов
/ 04 марта 2012

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

String temp = "(" + easnum1 + op1 + easnum2 + ")" + op2 + easnum3;

, после этого вы можете использовать класс ScriptEngineManager для использования javascript в качестве движка, чтобы вы могли использовать метод eval.

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");        
Object result = engine.eval(temp);

этот метод выполняет вычисления и возвращает результат.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...