2011-01-26 7 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; 

範囲のオーバーランエラーが発生しています。実際に範囲外になった場所は表示されません。私がこの関数でしようとしているのは、bと等しいNの長さの配列の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. コードは、同じ番号/インデックスの位置を繰り返しないよう保護していません。 、アプローチはO(N^C)であることを特徴とする

    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; 
    

は、おそらくより多くのような何かをしたいです。配列をソートし、再帰的なステップを答えを保持できる配列の部分に制限するか、配列のc個の数値の組み合わせを扱うことで、それよりも優れた処理を行うことができます。このフォーラムには、回答がよく似ているmanyという質問があります。