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 要素の合計を見つけようとすることです。私を助けてください。

4

2 に答える 2

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

評価結果は rezultatas と baigti にも依存するため、liko_skatimenu が 0 の場合に false と評価される可能性があります。次回に進行する場合は ats[-1] := i;、これはおそらくあなたが望んでいたものではありません. 私はそれを次のように変更します:

if (liko_skaitmenu = 0) or ((not baigti) and (rezultatas = b)) then
于 2011-01-26T18:43:59.660 に答える
0

コードは理解を困難にするいくつかのグローバル変数を使用しており、プロシージャが呼び出される前に変数がどのように初期化されるかを示していません。コードサンプルが英語の場合にも役立ちます。

ともかく、

  1. このコードは、の可能性を防ぎませんrezultatas > b
  2. の複雑な条件のため、はのifats[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数の組み合わせを操作することもできます。このフォーラムには、良い答えのある同様の質問がたくさんあります。

于 2011-01-26T19:13:54.517 に答える