Marijus
Marijus

Reputation: 4365

Pascal range overrun

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;

So I'm getting range overrun error, and I don't see where I really got out of range. What I'm trying to do with this function is try to find sum of c elements in N length array that equals b. Please help me.

Upvotes: 0

Views: 750

Answers (2)

Apalala
Apalala

Reputation: 9224

The codes uses several global variables that make it difficult to understand, and you don't show how the variables are initialized before the procedure is called. It would also help if the code sample was in English.

Any way,

  1. The code doesn't guard against the possibility of rezultatas > b.
  2. Because of the complex condition on the if, the ats[liko_skaitmenu] := i; may be executed with values of liko_skaitmenu < 1.
  3. The code doesn't guard against repeating the same number/index position.

You probably want something more like:

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;

That said, the approach is O(N^c). You can do better than that by sorting the array and restricting the recursive step to parts of the array that can hold the answer, or you can work with the combinations of c numbers in the array. There are many alike questions with good answers in this forum.

Upvotes: 0

BlackBear
BlackBear

Reputation: 22979

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

There's the possibility that this evaluates to false when liko_skatimenu is 0, because the result of the evaluation depends on rezultatas and baigti too. If it proceeds next time you'll have ats[-1] := i;, which probably isn't what you wanted. I'd change it into something like:

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

Upvotes: 1

Related Questions