Reputation: 4365
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
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,
rezultatas > b
.if
, the ats[liko_skaitmenu] := i;
may be executed with values of liko_skaitmenu < 1
.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
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