Algorithm 使用递归计算数组中的对象数
我对递归有一些问题,为了理解它,我试图为自己编造问题并解决它们。这个问题让我感到困惑: 将此视为字符串形式的输入:Algorithm 使用递归计算数组中的对象数,algorithm,recursion,Algorithm,Recursion,我对递归有一些问题,为了理解它,我试图为自己编造问题并解决它们。这个问题让我感到困惑: 将此视为字符串形式的输入: [[a,b,c],[[d]],[[e,f]],[g],h,i,[[j,[k,l]]]] 目标是找到列表中的事物总数以及它们自身的列表。对于本例,结果将是:12+10=22 请注意,输入不是数组,而是字符串。也不是a,b,。。。 任何东西都可以使用,如数字、字符串等。 [12345,0.34,["afv",24]] 这是我的想法,但我会提到为什么我不能实现它: 我们编写一个开始迭
[[a,b,c],[[d]],[[e,f]],[g],h,i,[[j,[k,l]]]]
目标是找到列表中的事物总数以及它们自身的列表。对于本例,结果将是:12
+10
=22
请注意,输入不是数组,而是字符串。也不是a
,b
,。。。
任何东西都可以使用,如数字、字符串等。[12345,0.34,["afv",24]]
这是我的想法,但我会提到为什么我不能实现它:我们编写一个开始迭代字符串的函数。它应该计算
[
和]
之间的总数。每当函数到达[
时,它就会调用自己迭代剩余的字符串。这样它就可以深入数组。这些是我的问题:
公共静态整数计数器(字符串a){
整数和=0;
//一些用于迭代字符串的代码
//一些代码检查条件,如果需要,调用该方法
//一些代码将对象数和数组数相加
回报金额;
}
谢谢您的时间。根据您设计递归算法和输入大小的方式,您可能会遇到递归堆栈溢出的常见问题,其中递归非常深,内存空间不足 这是一个不同的迭代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)
由于您不关心解析列表的实际内容(为此您将实现一个递归下降解析器),因此可以实现一个简单的状态机 这里是一个非常粗略的,部分的伪代码实现,目的是让您了解如何实现它。理想情况下,您会有更多的状态来检测语法错误:
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;
}
下面是JavaScript中的一个递归,它可能会给您一些想法
函数f(s){
函数nextIndexTranstr(i){
而(!(s[i]=“\”&&s[i-1]!=“\”)
i++;
返回i+1;
}
函数nextIndexafterNum(i){
而(![”,“,”]“]包括(s[i]))
i++;
返回i;
}
//返回[nummarays、nummements、endIndex]
//假定输入有效
功能g(i、as、es){
//基本情况
如果(s[i]==”]“|i==s.length)
返回[as,es,i];
如果(s[i]==“,”)
返回g(i+1,as,es);
//单子
如果(s[i]=“[”){
常数[aas,ees,endIndex]=g(i+1,0,0);
返回g(endIndex+1,as+1+aas,es+ees);
}
//字符串元素
如果(s[i]=“\”)
返回g(nextIndexafterStr(i+1),as,es+1);
//数字或变量名元素
返回g(nextIndexafterNum(i),as,es+1);
}
常数[as,es,z]=g(0,0,0);
返回as+es;
}
var a=[12345,0.34,[“af\“v”,24];
变量b=“[a,b,c],[d],[e,f],[g],h,i,[[j[k,l]]”;
a=JSON.stringify(a);
控制台日志(a);
控制台日志(f(a));
控制台日志(b);
控制台。log(f(b));这可能过于简单化,考虑诸如<代码> [ a,b,c ] < < /代码>的情况。注意:这不包括元素可以用逗号嵌入字符串的情况,例如“Hello,那里”。"@Jae Yang tnx的解决方案,但我想知道递归的解决方案。另外,您必须使用java中的regx来拆分字符串,也可以使用算法来拆分字符串,但如果字符串的长度为10000个字符,我认为拆分字符串并将其放入数组或列表中不会非常省时。不要尝试所有操作同时,这将导致非常复杂的代码,你可能会丢失。第一步是把输入解析成一个抽象的语法树,它反映了结构,然后进行计数。“对不起,亨利,我只是一个业余爱好者,你能解释更多的细节吗?你的基本思想是正确的。ser'这是一个众所周知的算法。@IanMercer是的,有人告诉我这个名字,我搜索了它。但实际上我很难编写代码。尽管如果你真的不关心里面的内容,并且你确信输入格式正确,你可能只需要一个简单的状态机。状态1=正常。状态2=在某种情况下,状态3=在引用的内容中。读取每个字符,根据状态句柄计数,根据需要更改状态,…查找“有限状态机”。它是如何递归的?不是;请参阅问题的注释。如果您想要递归,请创建递归下降解析器,但对于指定的目标,您不需要它。