为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

DIEA 2023-10-13 09:57:57
该方法必须接收Stringin 格式"[1,2,3,4,5]",其中仅包含整数,但它也可以包含"[1,2,3,[]]"or "[1,2,3,[1,2,3]]"。我已经有了将数字添加到列表中的代码,但我不知道当我List里面有另一个数字时如何处理。我想过有一个类List,当我在里面找到另一个括号再次调用该函数时,但当我看到另一个左括号时不知道如何正确地进行子字符串化[。删除括号后,我将字符串分割如下:String[] arr = string.split(",");并开始将这些结果添加到List我必须返回 a for loop,我的问题是当我再次看到左括号时,[我必须String再次使用结果子串并调用我的方法,但不知道如何确定右括号。我尝试过的是获取右括号的索引indexOf:String aux = arr[i]; int closingBracket = aux.indexOf("]");[1,2,3,4,[,6]但如果我有一个不应该被接受的输入字符串,它会接受它。
查看完整描述

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);

   }

}


请注意,在上面的示例中,“状态”实际上是“伪状态”。也就是说,您不需要检查当前所处的状态来确定如何处理当前令牌或标记错误。


查看完整回答
反对 回复 2023-10-13
  • 1 回答
  • 0 关注
  • 91 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信