该方法必须接收格式为String
的{{1}},其中仅包含整数,但是也可以包含"[1,2,3,4,5]"
或"[1,2,3,[]]"
。我已经有了将数字添加到列表中的代码,但是当我里面有另一个"[1,2,3,[1,2,3]]"
时,我不知道该如何处理。
我曾考虑过有一个类List
,并且当我在里面找到另一个括号来再次调用该函数时,但是当我看到另一个开头的括号List
时,我不知道如何正确地进行子字符串化。
卸下方括号后,按如下所示分割字符串:
[
然后开始将这些结果添加到String[] arr = string.split(",");
中,我必须返回一个List
,我的问题是,当我再次看到一个开括号for loop
时,我必须进行子字符串调用再次使用生成的[
我的方法,但不知道如何确定右括号。我尝试过的是使用String
获取右括号的索引:
indexOf
但是如果我有一个不应该接受的String aux = arr[i];
int closingBracket = aux.indexOf("]");
这样的输入字符串,它将接受它。
答案 0 :(得分:0)
您需要做的是在纸上找出所谓的有限状态机(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
假设您要将所有这些内容保存在列表列表中,那么最简单的方法是从List<Object>
开始,因为您可以在该类型的列表中保存integers
和lists of lists
深度不确定。
我还建议您查看Stack class
。您可能想推送当前列表,并随着解析深度的变化弹出最近的列表。
最后,确保括号与以下各项正确匹配。看到“ [”时增加一个计数器,当看到“]”时减少一个计数器。如果计数器变为负数,则右括号过多。如果最后是正数,则说明您没有足够的右括号。
有关更多信息,请访问Wikipedia上的Finite State Machines。
我决定提供一个我所谈论的例子。它可能无法涵盖所有可能的极端情况,但目的只是为了说明。
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);
}
}
请注意,在上面的示例中,“状态”是“伪状态”。也就是说,您无需检查当前状态即可确定如何处理当前令牌或标记错误。
答案 1 :(得分:0)
尝试类似的操作:
import java.util.ArrayList;
import java.util.Iterator;
public class RecursiveListIterator{
public static void main(String[] args){
String str = "[1,2,3,[],[1,2,3,[4,5,6],[]],7,[],[[],[],[8]]]";
try{
ArrayList<?> list = generateListFromString(str);
String listBackToString = generateStringFromList(list);
System.out.println(str);
System.out.println(listBackToString);
}
catch(ExceptionBracketsDoesNotMatch e){
System.out.println("ERROR: Brackets does not match!");
e.printStackTrace();
}
System.exit(0);
}
public static ArrayList<Object> generateListFromString(String str) throws ExceptionBracketsDoesNotMatch {
ArrayList<Object> list = new ArrayList<Object>();
populateList(str, list);
return list;
}
private static void populateList(String str, ArrayList<Object> list) throws ExceptionBracketsDoesNotMatch {
if(!validateBracketsNumber(str)) {
throw new ExceptionBracketsDoesNotMatch("Brackets does not match!");
}
ArrayList<String> items = getItemsOfTheList(str);
Iterator<String> iterator = items.iterator();
while (iterator.hasNext()){
String item = iterator.next();
if(item.contains("[")) {
ArrayList<Object> sublist = new ArrayList<Object>();
populateList(item, sublist);
list.add(sublist);
}
else{
list.add(item);
}
}
}
private static ArrayList<String> getItemsOfTheList(String str) throws ExceptionBracketsDoesNotMatch{
ArrayList<String> items = new ArrayList<String>();
String digitStr = "";
for(int i=1; i<str.length(); i++){
char ch = str.charAt(i);
if(ch == '[') {
int indexCloseBracket = getIndexThatClosesTheBracket(i, str);
String sublist = str.substring(i, indexCloseBracket+1);
items.add(sublist);
i = indexCloseBracket+1;
}
else if (ch == ',' || ch == ']') {
items.add(digitStr);
digitStr = "";
}
else {
digitStr += ch;
}
}
return items;
}
private static int getIndexThatClosesTheBracket(int indexBracket, String str) throws ExceptionBracketsDoesNotMatch{
int countBrackets = 0;
for(int i=indexBracket; i<str.length(); i++){
if(str.charAt(i) == '[') {
countBrackets++;
}
else if(str.charAt(i) == ']') {
countBrackets--;
if(countBrackets==0) {
return i;
}
}
}
throw new ExceptionBracketsDoesNotMatch("Brackets does not match!");
}
private static boolean validateBracketsNumber(String str){
int countBrackets = 0;
for(int i=0; i<str.length(); i++){
if(str.charAt(i) == '[') {
countBrackets++;
}
else if(str.charAt(i) == ']') {
countBrackets--;
}
if(countBrackets<0) {
return false;
}
}
return countBrackets==0;
}
private static String generateStringFromList(ArrayList<?> list) {
String str = "";
boolean hadIteraction = false;
Iterator<?> iterator = list.iterator();
while (iterator.hasNext()){
if(hadIteraction) {
str += ",";
}
else {
hadIteraction = true;
}
Object item = iterator.next();
if(item instanceof String) {
str += item;
}
else if(item instanceof ArrayList<?>) {
str += generateStringFromList((ArrayList<?>)item);
}
}
return "[" + str + "]";
}
static class ExceptionBracketsDoesNotMatch extends Exception{
public ExceptionBracketsDoesNotMatch(String arg0){
super(arg0);
}
}
}