我想标记一个由整数,浮点数,运算符,函数,变量和括号组成的字符串。以下示例应该提亮问题的本质:
现状:
String infix = 4*x+5.2024*(Log(x,y)^z)-300.12
期望状态:
String tokBuf[0]=4
String tokBuf[1]=*
String tokBuf[2]=x
String tokBuf[3]=+
String tokBuf[4]=5.2024
String tokBuf[5]=*
String tokBuf[6]=(
String tokBuf[7]=Log
String tokBuf[8]=(
String tokBuf[9]=x
String tokBuf[10]=,
String tokBuf[11]=y
String tokBuf[12]=)
String tokBuf[13]=^
String tokBuf[14]=z
String tokBuf[15]=)
String tokBuf[16]=-
String tokBuf[17]=300.12
所有提示和解决方案都将受到赞赏。
答案 0 :(得分:6)
使用Java流标记器。界面有点奇怪,但人们会习惯它:
http://docs.oracle.com/javase/7/docs/api/java/io/StreamTokenizer.html
解析到请求的String列表的示例代码(您可能希望直接使用tokenizer或至少使用Object列表,这样您可以直接将数字存储为Double):
public static List<String> tokenize(String s) throws IOException {
StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(s));
tokenizer.ordinaryChar('-'); // Don't parse minus as part of numbers.
tokenizer.ordinaryChar('/'); // Don't treat slash as a comment start.
List<String> tokBuf = new ArrayList<String>();
while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
switch(tokenizer.ttype) {
case StreamTokenizer.TT_NUMBER:
tokBuf.add(String.valueOf(tokenizer.nval));
break;
case StreamTokenizer.TT_WORD:
tokBuf.add(tokenizer.sval);
break;
default: // operator
tokBuf.add(String.valueOf((char) tokenizer.ttype));
}
}
return tokBuf;
}
试运行:
System.out.println(tokenize("4*x+5.2024*(Log(x,y)^z)-300.12"));
[4.0, *, x, +, 5.2024, *, (, Log, (, x, ,, y, ), ^, z, ), -, 300.12]
答案 1 :(得分:1)
http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form
http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools
算法示例:
步骤#1 :读取'4'=&gt;数字标记=&gt;读取字符直到达到非num符号(即'*')。第一个刚读过,tokBuf [0]是一个数字标记
步骤#2 :读取'*'=&gt; token表示二元运算符
步骤#3 :读取'x'。或许,功能符号=&gt;将下一个标记标记为var-token
等等。
下一步是评估,我猜?反向波兰表示法或语法树将有助于......