递归计算数组中的对象数

时间:2018-12-14 06:23:37

标签: algorithm recursion

我在递归方面遇到一些问题,为了理解它,我正在尝试为自己解决问题并加以解决。这个特殊的问题使我感到困惑: 将此视为字符串形式的输入:

[[a,b,c],[[d]],[[e,f]],[g],h,i,[[j,[k,l]]]]

目标是查找列表中的事物总数,并将其自身列出。对于这个示例,结果将是:12 + 10 = 22 请注意,输入不是数组,而是字符串。也可以代替ab,... 可以使用任何东西,例如数字,字符串等。

[12345,0.34,["afv",24]]

这是我的主意,但我会提及为什么无法实现它:
我们编写了一个开始迭代字符串的函数。该函数应该计算[]之间的总和。每当函数达到[时,它就会调用自己以迭代剩余的字符串。这样,它可以更深入地进入数组。
这些是我的问题:

  1. 我不知道我的想法是否正确。
  2. 如果我的想法正确,那么基本情况是什么。
  3. 我如何确保不管它们是什么,它都对里面的所有东西都计数?(我的意思是我如何确保它对数字,字符串等的对待相同)
  4. 我认为函数的主体应如下所示(我在这里使用的是Java,但我认为此处的语言并不重要):

    public static int counter(String a){ int sum = 0; //some code to iterate the string //some code to check the conditions and if needed call the method //some code to add the number of objects and arrays to sum return sum; }

如果代码应符合我的要求,那么我该如何填充内容? 谢谢您的宝贵时间。

3 个答案:

答案 0 :(得分:1)

取决于您设计递归算法的方式和输入的大小,您可能会遇到递归堆栈溢出的常见问题,在该问题中,递归非常深并且内存空间不足

如果您不必(不必)使用递归,则这是一个不同的迭代pythonic解决方案,但是您应该可以将其转换为Java。

您希望增加用逗号分隔的每个项目的计数。但是,如果该元素具有']'字符,则说明它是嵌入列表的一部分。通过计算右花括号和元素,可以得到总数。

已更新以处理带有嵌入式逗号的字符串

# Function for removing the chars between apostrophes
def remove(s,c):
    while(s.find(c) != -1):
        i = s.find(c) # find the first instance of c but ' or " in our case
        i2 = s.find(c,i+1) # find the second instance
        s = s[0:i]+s[i2+1:] # Remove the string
        return s
    return s

s = "[['a,b,c'],[1,2,3]]"
s = s[:-1] # remove the last list char
total = 0
s = remove(s,'\'')
s = remove(s,'"')
l = s.split(',')
for el in l:
    total+=1
    total+= el.count(']')
print(total)

答案 1 :(得分:1)

由于您不关心解析列表的实际内容(为此您将实现递归下降解析器),因此您可以实现简单的状态机。

这是伪代码中的非常粗糙部分实现,目的只是为了让您对如何实现此想法有所了解。理想情况下,您应该具有更多状态来检测语法错误:

int lists, elements = 0;
state = normal;
foreach (char c in input)
{
   switch state
      case normal:
        if (c == '[')
          lists++;
        else if (c == ']')
          // do nothing
        else if (c == ',')
          // do nothing (will only count [ and , on elements)
        else if (c == '"')
          elements++;
          state = quoted_element
        else
          elements++;
          state = element; 
        break;

      case quoted_element:
        if (c == '"')
          state = element;
        break;

      case element:
        if (c == '"' || c == '[')
          exception("Syntax error");
        else if (c == ",")
          elements++;
        else if (c == "]")
          state = normal;
        break;
}

答案 2 :(得分:1)

这是JavaScript的递归,可能会给您一些想法。

function f(s){
  function nextIndexafterStr(i){
    while (!(s[i] == "\"" && s[i-1] != "\\"))
      i++;
    return i + 1;
  }

  function nextIndexafterNum(i){
    while (![",", "]"].includes(s[i]))
      i++;
    return i;
  }

  // Returns [numArrays, numElements, endIndex]
  // Assumes valid input
  function g(i, as, es){
    // base case
    if (s[i] == "]" || i == s.length)
      return [as, es, i];

    if (s[i] == ",")
      return g(i + 1, as, es);

    // a list
    if (s[i] == "["){
      const [aas, ees, endIndex] = g(i + 1, 0, 0);
      return g(endIndex + 1, as + 1 + aas, es + ees);
    }

    // string element
    if (s[i] == "\"")
      return g(nextIndexafterStr(i + 1), as, es + 1);

    // number or variable-name element
    return g(nextIndexafterNum(i), as, es + 1);
  }

  const [as, es, _] = g(0, 0, 0);
  return as + es;
}


var a = [12345,0.34,["af\"v",24]];
var b = "[[a,b,c],[[d]],[[e,f]],[g],h,i,[[j,[k,l]]]]";

a = JSON.stringify(a);
console.log(a);
console.log(f(a));
console.log(b);
console.log(f(b));