将带有括号的逗号分隔字符串传递到列表

时间:2019-10-09 21:15:56

标签: java

该方法必须接收格式为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("]"); 这样的输入字符串,它将接受它。

2 个答案:

答案 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>开始,因为您可以在该类型的列表中保存integerslists 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);
        }       
    }

}