我正在尝试将用户给出的输入分成我的计算器。 例如, 如果用户输入“23 + 45 *(1 + 1)”,我希望将其拆分为[23,+,45,*,(,1,+,1,)]。
答案 0 :(得分:7)
您所寻找的是词法分析器。 词法分析器将输入拆分为您可以阅读的块(称为令牌)。
幸运的是,你的词法分析器很简单,可以手工编写。对于更复杂的词法分析器,您可以使用flex
(如“快速词法分析器” - 而非Adobe Flex),或(因为您使用的是Java)ANTLR(注意,ANTLR更多而不只是一个词法分析员。)
只需提供一个正则表达式列表,每个令牌匹配一个(请注意,由于您的输入非常简单,您可以取消此列表并将它们全部合并到一个正则表达式中。但是,更多信息高级词法分析器,它有助于为每个标记执行一个正则表达式)例如
\d+
\+
-
*
/
\(
\)
然后启动循环:当有更多要解析的字符时,请遍历每个正则表达式并尝试将它们与字符串的开头匹配。如果匹配,请将第一个匹配的组添加到输入列表中。否则,继续匹配(如果它们都不匹配,告诉用户他们有语法错误)。
伪代码:
List<String>input = new LinkedList<String>();
while(userInputString.length()>0){
for (final Pattern p : myRegexes){
final Matcher m = p.matcher(userInputString);
if(m.find()) {
input.add(m.group());
//Remove the token we found from the user's input string so that we
//can match the rest of the string against our regular expressions.
userInputString=userInputString.substring(m.group().length());
break;
}
}
}
实施说明:
^
字符添加到所有正则表达式中。这样可以确保将匹配项锚定在字符串的开头。我的伪代码假设你已经这样做了。答案 1 :(得分:1)
我认为使用 stacks 来拆分操作数和运算符并评估表达式会更合适。在计算器中,我们通常使用中缀符号来定义算术表达式。
Operand1 op Operand2
检查许多此类情况中使用的Shunting-yard algorithm以解析数学表达式。 This也是一本很好的读物。
答案 2 :(得分:0)
这可能有点草率,因为我还在学习,但它确实将它们分成了字符串。
公共类TestClass {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
ArrayList<String> separatedInput = new ArrayList<String>();
String input = "";
System.out.print("Values: ");
input = sc.next();
if (input.length() != 0)
{
boolean numberValue = true;
String numbers = "";
for (int i = 0; i < input.length(); i++)
{
char ch = input.charAt(i);
String value = input.substring(i, i+1);
if (Character.isDigit(ch))
{ numberValue = true; numbers = numbers + value; }
if (!numberValue)
{ separatedInput.add(numbers); separatedInput.add(value); numbers = ""; }
numberValue = false;
if (i == input.length() - 1)
{
if (Character.isDigit(ch))
{ separatedInput.add(numbers); }
}
}
}
System.out.println(separatedInput);
}
}