1 回答
TA贡献1789条经验 获得超10个赞
您需要做的是在纸上弄清楚什么是有限状态机 (FSM)。当你遇到一个标记(逗号、括号、数字)时,你就进入了一个特定的状态。一旦处于某种状态,您只能接受某些其他令牌,这可能会使您处于不同的状态或使您处于当前状态。您可以有许多不同的状态,它们可以接受不同的令牌并执行不同的操作。
例如。
当您看到一个数字时,下一个标记可能是。
1. Another digit
2. A closing bracket.
3. A comma.
这些令牌中的每一个都可以提示不同的状态和/或动作。
1. Another digit - keep on processing since numbers have many digits.
2. closing bracket - save the number in a list and get the next list (See below)
3. comma - save the number and look for next number
假设您想将所有这些保存在列表列表中,最简单的方法是从 a 开始,List<Object>因为您可以将integers和保存lists of lists在具有无限深度的那种类型的列表中。
我还建议你看看Stack class。随着解析深度的变化,您可能希望推送当前列表并弹出最近的列表。
最后,确保您的括号与以下内容正确匹配。当您看到“[”时增加计数器,当您看到“]”时减少计数器。如果计数器变为负数,则说明右括号过多。如果最后它是正数,则说明您没有足够的右括号。
有关这方面的更多信息,请查看维基百科上的有限状态机。
我决定用一个小例子来说明我正在谈论的内容。它可能无法涵盖所有可能的边缘情况,但其目的是说明性的。
public static void main(String[] args) {
String strlist =
"[1,2,113], [4,5,[5,2,10],1], [],[1,2,3,4,5,[10,11,12,13,[14,15]]]";
int bracketCount = 0;
int num = 0;
// inital list
List<Object> list = new ArrayList<>();
// hold sublists for precessing
Stack<List<Object>> stack = new Stack<>();
char[] chars = strlist.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
switch (c) {
// state1 left bracket - push current list on stack for later
// retrieval
// allocate new list and add it to one just pushed (remember,
// I still have its reference).
// Assign nlist to list
// increment bracket count
case '[':
stack.push(list);
List<Object> nlist = new ArrayList<>();
list.add(nlist);
list = nlist;
bracketCount++;
break;
// state2 right bracket - Finished processing current sublist.
// if previous tokens were not brackets, then add the
// number to the list and pop off the previous one.
// decrement bracket count
case ']':
if (chars[i - 1] != '[' && chars[i - 1] != ']') {
list.add(num);
}
list = stack.pop();
bracketCount--;
break;
// state3 - whitespace - ignore
case ' ':
case '\t':
break;
// state4 comma - if previous token was not a right bracket,
// then add number. Reset num for next number.
case ',':
if (chars[i - 1] != ']') {
list.add(num);
}
num = 0;
break;
// state5 digit - assumed to be a digit. Each time a digit
// is encountered, update the number
default:
num = num * 10 + c - '0';
}
if (bracketCount < 0) {
System.out.println("too many ] brackets at location " + i);
}
}
if (bracketCount > 0) {
System.out.println("insufficent number of ] brackets");
}
System.out.println(list);
}
}
请注意,在上面的示例中,“状态”实际上是“伪状态”。也就是说,您不需要检查当前所处的状态来确定如何处理当前令牌或标记错误。
添加回答
举报