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);
}
}
請注意,在上面的示例中,“狀態”實際上是“偽狀態”。也就是說,您不需要檢查當前所處的狀態來確定如何處理當前令牌或標記錯誤。
添加回答
舉報