2015-01-06 2 views
4

Я пытаюсь разбить математическое выражение.Разделение Java с математическим выражением

String number = "100+500"; 

String[] split = new String[3]; 

Хочу сделать

  • сплит [0] = "100"
  • разделенным [1] = "+"
  • раскол [2] = "500"

Я пробовал это, но я не знаю, что писать для расщепления.

split = number.split(????); 
+3

Почему вы хотите разбить его? Чтобы написать парсер или оценить выражение? В обоих случаях раскол, вероятно, не самый правильный инструмент. – assylias

+0

@assylias Я делаю калькулятор GUI для больших целых чисел. После расщепления я проверю, какой оператор используется, тогда я буду его оценивать. – berkc

+2

Сплит использует регулярное выражение, поэтому это может быть интересно: http://stackoverflow.com/questions/24463048/ruby-find-a-whole-math-expression-in-a-string-using-regex – Christian

ответ

6

Вы хотите разделить между цифрами и нецифровыми без потребления какого-либо входа ... Вы должны выглядеть обходные:

String[] split = number.split("(?<=\\d)(?=\\D)|(?<=\\D)(?=\\d)"); 

Какого черт, что крушение поезда из регулярных выражений?

Это выражающее первоначальное предложение этого ответа:

  • (?<=\d) означает, что предыдущий символ является цифрой
  • (?=\D) означает следующий символ является нецифровой
  • (?<=\d)(?=\D) вместе будет соответствовать между a цифра и незначение
  • regexA|regexB означает либо регулярное выражениеA , либо regexB подобран, который используется в качестве пунктов выше, но нецифровой то цифра для визы наборот логики

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


Вот некоторые тестовый код:

String number = "100+500-123/456*789"; 
String[] split = number.split("(?<=\\d)(?=\\D)|(?<=\\D)(?=\\d)"); 
System.out.println(Arrays.toString(split)); 

Выход:

[100, +, 500, -, 123, /, 456, *, 789] 
+0

Это сработало ... но как? Что означает «(? <= \\ d) (? = \\ D) | (? <= \\ D) (? = \\ d)" означает? – berkc

+0

@Dosher: ознакомьтесь с http://docs.oracle.com/javase/tutorial/essential/regex/. Предопределенные классы символов объясняют, что делают \ d и \ D. Другие методы должны объяснять остальное регулярное выражение. – DivineWolfwood

+0

@dosher see редактирует ответ для объяснения – Bohemian

3

С летучей мыши, я не знаю никакой библиотечной процедуры для раскола. Рутинная обычай расщепления может быть так:

/** 
* Splits the given {@link String} at the operators +, -, * and/
* 
* @param string 
*   the {@link String} to be split. 
* @throws NullPointerException 
*    when the given {@link String} is null. 
* @return a {@link List} containing the split string and the operators. 
*/ 
public List<String> split(String string) throws NullPointerException { 
    if (string == null) 
     throw new NullPointerException("the given string is null!"); 
    List<String> result = new ArrayList<String>(); 

    // operators to split upon 
    String[] operators = new String[] { "+", "-", "*", "/" }; 

    int index = 0; 
    while (index < string.length()) { 
     // find the index of the nearest operator 
     int minimum = string.length(); 
     for (String operator : operators) { 
      int i = string.indexOf(operator, index); 
      if (i > -1) 
       minimum = Math.min(minimum, i); 
     } 

     // if an operator is found, split the string 
     if (minimum < string.length()) { 
      result.add(string.substring(index, minimum)); 
      result.add("" + string.charAt(minimum)); 
      index = minimum + 1; 
     } else { 
      result.add(string.substring(index)); 
      break; 
     } 
    } 

    return result; 
} 

Некоторые тест-код:

System.out.println(split("100+10*6+3")); 
System.out.println(split("100+")); 

Выход:

[100, +, 10, *, 6, +, 3] 
[100, +] 
+0

Я тоже буду использовать это, большое вам спасибо! – berkc

1

Вы можете сделать что-то простое вместо безумного регулярных выражений; просто подушечка + с белым пространством:

String number = "100+500"; 
number = number.replace("+", " + "); 

Теперь вы можете разделить его на белом пространстве:

String[] split = number.split(" "); 

Теперь ваши индексы будут установлены:

split[0] = "100"; 
split[1] = "+"; 
split[2] = "500"; 

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

public static String replacing(String s) { 
    String[] chars = {"+", "-", "/", "="}; 

    for (String character : chars) { 
     if (s.contains(character)) { 
     s = s.replace(character, " " + character + " ");//not exactly elegant, but it works 
     } 
    } 
    return s; 
} 

//in main method 
number = replacing(number); 
String[] split = number.split(" "); 
+0

Это отличный метод для меня, но мне также нужно разделить - и *. Будет ли number = number.replace ("+", "+" || "-", "-" || "*", "*"); Работа? --Edit: ОК, это не сработало. – berkc

+0

К сожалению, вам нужно будет включить '.replace()' для каждого символа, который вы хотите использовать для этой техники.Обходной путь заключается в создании метода, который будет проверять все области, которые нужно разбить, и постоянно обновлять строку, а затем возвращать ее. Ваши символы, такие как '*' и '-', могут быть помещены в массив, который нужно перебрать. Вы должны только написать 'replace()' один раз, поэтому ваш код будет выглядеть более элегантным. Производительность все равно будет одинаковой. –

2

Вы также можете использовать классы Pattern/Сличитель в Java:

String expression = "100+34"; 
    Pattern p = Pattern.compile("(\\d+)|(\\+)"); 
    Matcher m = p.matcher(expression); 
    String[] elems = new String[m.groupCount() +1]; 
    int i=0; 

    while(m.find()) 
    { 
     elems[i++] = m.group(); 
    } 
+0

Обновлено для возврата массива, как в примере. – panagdu

0

Вы можете разделить ваша строка выражения, а затем результат, имеющий p ure и обозначенные жетоны. Библиотека mXparser поддерживает это, а также процесс расчета. Пожалуйста, следуйте приведенным ниже пример:

Ваш очень простой пример "100 + 500":

import org.mariuszgromada.math.mxparser.*; 
... 
... 
Expression e = new Expression("100+500"); 
mXparser.consolePrintTokens(e.getCopyOfInitialTokens()); 

Результат:

[mXparser-v.4.0.0] -------------------- 
[mXparser-v.4.0.0] | Expression tokens: | 
[mXparser-v.4.0.0] --------------------------------------------------------------------------------------------------------------- 
[mXparser-v.4.0.0] | TokenIdx |  Token |  KeyW |  TokenId | TokenTypeId | TokenLevel | TokenValue | LooksLike | 
[mXparser-v.4.0.0] --------------------------------------------------------------------------------------------------------------- 
[mXparser-v.4.0.0] |   0 |   100 |  _num_ |   1 |   0 |   0 |  100.0 |    | 
[mXparser-v.4.0.0] |   1 |   + |   + |   1 |   1 |   0 |   NaN |    | 
[mXparser-v.4.0.0] |   2 |   500 |  _num_ |   1 |   0 |   0 |  500.0 |    | 
[mXparser-v.4.0.0] --------------------------------------------------------------------------------------------------------------- 

Более сложный пример «2 * sin (х) + (3/соз (у) -e^(син (х) + у)) + 10" :

import org.mariuszgromada.math.mxparser.*; 
... 
... 
Argument x = new Argument("x"); 
Argument y = new Argument("y"); 
Expression e = new Expression("2*sin(x)+(3/cos(y)-e^(sin(x)+y))+10", x, y); 
mXparser.consolePrintTokens(e.getCopyOfInitialTokens()); 

Результат:

[mXparser-v.4.0.0] -------------------- 
[mXparser-v.4.0.0] | Expression tokens: | 
[mXparser-v.4.0.0] --------------------------------------------------------------------------------------------------------------- 
[mXparser-v.4.0.0] | TokenIdx |  Token |  KeyW |  TokenId | TokenTypeId | TokenLevel | TokenValue | LooksLike | 
[mXparser-v.4.0.0] --------------------------------------------------------------------------------------------------------------- 
[mXparser-v.4.0.0] |   0 |   2 |  _num_ |   1 |   0 |   0 |   2.0 |    | 
[mXparser-v.4.0.0] |   1 |   * |   * |   3 |   1 |   0 |   NaN |    | 
[mXparser-v.4.0.0] |   2 |   sin |   sin |   1 |   4 |   1 |   NaN |    | 
[mXparser-v.4.0.0] |   3 |   (|   (|   1 |   20 |   2 |   NaN |    | 
[mXparser-v.4.0.0] |   4 |   x |   x |   0 |   101 |   2 |   NaN |    | 
[mXparser-v.4.0.0] |   5 |   ) |   ) |   2 |   20 |   2 |   NaN |    | 
[mXparser-v.4.0.0] |   6 |   + |   + |   1 |   1 |   0 |   NaN |    | 
[mXparser-v.4.0.0] |   7 |   (|   (|   1 |   20 |   1 |   NaN |    | 
[mXparser-v.4.0.0] |   8 |   3 |  _num_ |   1 |   0 |   1 |   3.0 |    | 
[mXparser-v.4.0.0] |   9 |   /|   /|   4 |   1 |   1 |   NaN |    | 
[mXparser-v.4.0.0] |   10 |   cos |   cos |   2 |   4 |   2 |   NaN |    | 
[mXparser-v.4.0.0] |   11 |   (|   (|   1 |   20 |   3 |   NaN |    | 
[mXparser-v.4.0.0] |   12 |   y |   y |   1 |   101 |   3 |   NaN |    | 
[mXparser-v.4.0.0] |   13 |   ) |   ) |   2 |   20 |   3 |   NaN |    | 
[mXparser-v.4.0.0] |   14 |   - |   - |   2 |   1 |   1 |   NaN |    | 
[mXparser-v.4.0.0] |   15 |   e |   e |   2 |   9 |   1 |   NaN |    | 
[mXparser-v.4.0.0] |   16 |   ^|   ^|   5 |   1 |   1 |   NaN |    | 
[mXparser-v.4.0.0] |   17 |   (|   (|   1 |   20 |   2 |   NaN |    | 
[mXparser-v.4.0.0] |   18 |   sin |   sin |   1 |   4 |   3 |   NaN |    | 
[mXparser-v.4.0.0] |   19 |   (|   (|   1 |   20 |   4 |   NaN |    | 
[mXparser-v.4.0.0] |   20 |   x |   x |   0 |   101 |   4 |   NaN |    | 
[mXparser-v.4.0.0] |   21 |   ) |   ) |   2 |   20 |   4 |   NaN |    | 
[mXparser-v.4.0.0] |   22 |   + |   + |   1 |   1 |   2 |   NaN |    | 
[mXparser-v.4.0.0] |   23 |   y |   y |   1 |   101 |   2 |   NaN |    | 
[mXparser-v.4.0.0] |   24 |   ) |   ) |   2 |   20 |   2 |   NaN |    | 
[mXparser-v.4.0.0] |   25 |   ) |   ) |   2 |   20 |   1 |   NaN |    | 
[mXparser-v.4.0.0] |   26 |   + |   + |   1 |   1 |   0 |   NaN |    | 
[mXparser-v.4.0.0] |   27 |   10 |  _num_ |   1 |   0 |   0 |  10.0 |    | 
[mXparser-v.4.0.0] --------------------------------------------------------------------------------------------------------------- 

Чтобы понять, что такое Token.tokenId и Token.tokenTypeId, вам нужно обратиться к разделу API documentation и parsertokens. Например, в классе оператора у вас есть

  1. Operator.TYPE_ID - это соответствует Token.tokenTypeId если Токен признан в качестве оператора
  2. Operator.OPERATOR_NAME_ID - это соответствует Token.tokenId если Токен признается конкретной OPERATOR_NAME.

Для лучшего понимания следуйте mXparser tutorial.

С уважением

Смежные вопросы