1 回答

TA貢獻(xiàn)1789條經(jīng)驗 獲得超10個贊
您需要做的是在紙上弄清楚什么是有限狀態(tài)機(jī) (FSM)。當(dāng)你遇到一個標(biāo)記(逗號、括號、數(shù)字)時,你就進(jìn)入了一個特定的狀態(tài)。一旦處于某種狀態(tài),您只能接受某些其他令牌,這可能會使您處于不同的狀態(tài)或使您處于當(dāng)前狀態(tài)。您可以有許多不同的狀態(tài),它們可以接受不同的令牌并執(zhí)行不同的操作。
例如。
當(dāng)您看到一個數(shù)字時,下一個標(biāo)記可能是。
1. Another digit
2. A closing bracket.
3. A comma.
這些令牌中的每一個都可以提示不同的狀態(tài)和/或動作。
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
假設(shè)您想將所有這些保存在列表列表中,最簡單的方法是從 a 開始,List<Object>因為您可以將integers和保存lists of lists在具有無限深度的那種類型的列表中。
我還建議你看看Stack class。隨著解析深度的變化,您可能希望推送當(dāng)前列表并彈出最近的列表。
最后,確保您的括號與以下內(nèi)容正確匹配。當(dāng)您看到“[”時增加計數(shù)器,當(dāng)您看到“]”時減少計數(shù)器。如果計數(shù)器變?yōu)樨?fù)數(shù),則說明右括號過多。如果最后它是正數(shù),則說明您沒有足夠的右括號。
有關(guān)這方面的更多信息,請查看維基百科上的有限狀態(tài)機(jī)。
我決定用一個小例子來說明我正在談?wù)摰膬?nèi)容。它可能無法涵蓋所有可能的邊緣情況,但其目的是說明性的。
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);
}
}
請注意,在上面的示例中,“狀態(tài)”實際上是“偽狀態(tài)”。也就是說,您不需要檢查當(dāng)前所處的狀態(tài)來確定如何處理當(dāng)前令牌或標(biāo)記錯誤。
添加回答
舉報