2011-01-26 86 views
0
procedure solve(liko_skaitmenu, rezultatas : integer); 
    var i, j : integer; 
begin 
    if (not baigti) and (liko_skaitmenu = 0) and (rezultatas = b) then 
     begin 
      for j := 1 to c do 
       WriteLn(ats[j]); 
      baigti := true; 
     end 

     else 
      for i := 1 to N do 
      begin 
       ats[liko_skaitmenu] := i; 
       solve(liko_skaitmenu-1,rezultatas + a[i]); 
      end; 
end; 

所以我得到范围溢出错误,并且我没有看到我真的超出了范围。我试图用这个函数做的是试着找到N长度数组中等于b的c元素的总和。请帮帮我。帕斯卡范围溢出

回答

1
if (not baigti) and (liko_skaitmenu = 0) and (rezultatas = b) then 

还有,当liko_skatimenu是0,因为评估的结果取决于rezultatas和baigti过这个计算结果为假的可能性。如果它下一次你会有ats[-1] := i;,这可能不是你想要的。我想它变成类似:

if (liko_skaitmenu = 0) or ((not baigti) and (rezultatas = b)) then 
0

的代码使用几个全局变量,因此很难理解,而且你不显示怎么程序调用之前变量进行初始化。如果代码样本是英文的,它也会有所帮助。

任何方式,

  1. 代码不警惕的rezultatas > b的可能性。
  2. 由于if上的复杂条件,ats[liko_skaitmenu] := i;可能会使用值liko_skaitmenu < 1执行。
  3. 代码不会防止重复相同的数字/索引位置。

你可能想要更多的东西一样:

if not baigti and (resultatas <= b) then (* if not told to stop, or off-range *) 
begin 
    if liko_skaitemu = 0 then 
    begin 
     (* finished searching: either success or failure *) 
     if resultatas = b then 
      (*success! save the values *) 
      baigti := true; 
     end; 
    end 
    else 
    begin 
     (* continue searching *) 
    end 
end; 

这就是说,该方法是O(N^C)。通过对数组进行排序并将递归步骤限制为可存储答案的数组部分,或者可以使用数组中的c个数的组合,您可以做得比这更好。在这个论坛有many相似的问题与良好的答案。