Разделить инфиксную строку на массив строк в 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);
}