Разделить инфиксную строку на массив строк в Java

Я работаю над мини-научным калькулятором, который работает на infix в postfix алгоритм. Мой ввод - инфиксная строка.. и мой infix в postfix логика преобразования требует array из string, Так, как я могу разделить строку инфикса как это:

 100+(0.03*55)/45-(25+55)

Для массива String, в котором каждый операнд и оператор является элементом массива. как это

 "100" , "+" , "(" , "0.03" , "*" , "55" , ")" , "/" , "45" , "-"

и так далее...

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

5 ответов

Очевидно, каждый символ является отдельным токеном, за исключением последовательных цифр, возможно, с точкой. Таким образом, простым решением будет итерация по строке, а затем, когда вы видите цифру, которой предшествует другая цифра (или десятичный разделитель, точка), вы добавляете символ в предыдущий токен, в противном случае добавляете его в новый токен.,

Вот код:

public static List<String> getTokens(String inputString) {
    List<String> tokens = new ArrayList<String>();
    // Add the first character to a new token. We make the assumption
    // that the string is not empty.
    tokens.add(Character.toString(inputString.charAt(0)));

    // Now iterate over the rest of the characters from the input string.
    for (int i = 1; i < inputString.length(); i++) {
        char ch = inputString.charAt(i); // Store the current character.
        char lch = inputString.charAt(i - 1); // Store the last character.

        // We're checking if the last character is either a digit or the
        // dot, AND if the current character is either a digit or a dot.
        if ((Character.isDigit(ch) || ch == '.') && (Character.isDigit(lch) || lch == '.')) {
            // If so, add the current character to the last token.
            int lastIndex = (tokens.size() - 1);
            tokens.set(lastIndex, tokens.get(lastIndex) + ch);
        }
        else {
            // Otherwise, add the current character to a new token.
            tokens.add(Character.toString(ch));
        }
    }
    return tokens;
}

Обратите внимание, что этот метод быстрее, чем большинство методов регулярных выражений.

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

expString.split("(?<=[-+*/\\(\\)])|(?=[-+*/\\(\\)])");

сделает трюк для вас.

Сказать,

String str = "100+(0.03*55)/45-(25+55)";
String[] outs = str.split("(?<=[-+*/\\(\\)])|(?=[-+*/\\(\\)])");
for (String element : outs)
{
    System.out.println(element);
}

Даст вам вывод,

100
+
(
0.03
*
55
)
/
45
-
(
25
+
55
)

Пожалуйста, проверьте мой эксперимент @ http://rextester.com/QEMOYL38160

Вы должны использовать Lookahead и оглядываться назад с разделением.

Это работает. Конечно, улучшите регулярное выражение, если вы хотите включить больше элементов.

public static void main(String[] args) {
    String input = "100+(0.03*55)/45-(25+55)";
    String test[] = input.split("((?<=[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]])|(?=[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]]))");
    System.out.println(Arrays.toString(test));
}

Обновить:

((?<=[a-z]]), означает, что он будет разделяться на основе любого символа и включать символ в разделенный массив также после элемента.

(?=[a-z]), означает, что он будет разделяться на основе любого символа и включать символ в разделенный массив перед каждым элементом.

|, является оператором или между двумя регулярными выражениями.

[\\+\\-\\*\\/\\(\\)\\{\\}\\[\\]]), это регулярное выражение, чтобы соответствовать возможным комбинациям

Вот алгоритм, который я бы использовал:

начать с пустого строкового массива и пустого строкового буфера

  • перейти от символа 0 к символу n
  • для текущего символа определите тип (цифра / точка, открытая пара, близкая пара, математические операторы)
  • если текущий тип символа совпадает с последним типом символа
  • добавить текущий символ в буфер
  • если не одно и то же, поместите буфер в массив строк и запустите новый буфер

Пожалуйста, взгляните на ответы на этот другой вопрос.

Это должно сделать трюк:

Pattern p = Pattern.compile("(?:(\\d+)|([+-*/\\(\\)]))");
Matcher m = p.matcher("100+(0.03*55)/45-(25+55)");
List<String> tokens = new LinkedList<String>();
while(m.find())
{
  String token = m.group( 0 ); //group 0 is always the entire match   
  tokens.add(token);
}
Другие вопросы по тегам