Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Сочетание массивов и условия

Автор: smith 25.12.2009 2:55

Ребята, привет! Писал я задачу вот по такому условию:
Даны натуральное число n и целые числа q, a1,…,an, где n≤1000. Если в последовательности a1,…,an есть хотя бы один член, равный q, то получить сумму всех членов, следующих за первым таким членом; в противном случае ответом должно служить количество отрицательных элементов.
Написал программулину, вроде все верно считает, даже не вроде, а точно верно! Но сегодня при защите получилось вот как интересно.
Преподаватель взглянув на эту программу:


program antipov;
var a: array [1..1000] of integer;
var q,n,k,i,b,s:integer;
begin
writeln('vvedi kolvo elementov posledovatelnosty');
readln(n);
writeln('vvedi chislo Q');
readln(q);
k:=0;
s:=0;
writeln('vvode elementy posledovatelnosty');
for i:=1 to n do begin
read(a[i]);
end;
for i:=1 to n do begin
if a[i]=q then begin b:=i+1; for i:=b to n do begin s:=s+a[i];
end;
writeln('summa elementov posle chisla Q=',s);
end;
end;
for i:=1 to n do
begin if a[i]<0 then k:=k+1;
end;
if s=0 then
writeln('kolvo otric.chisel=',k);
end.




Сказал, чтобы я изменил БУКВУ СЧЕТЧИКА ЦИКЛА. Что я и сделал, изменив программу до такого вида, естественно добавив в блок описаний новую переменную J(в строке, где заменена буква счетчика я поставил стрелки справа):

program antipov;
var a: array [1..1000] of integer;
var q,n,k,i,b,j,s:integer;
begin
writeln('vvedi kolvo elementov posledovatelnosty');
readln(n);
writeln('vvedi chislo Q');
readln(q);
k:=0;
s:=0;
writeln('vvode elementy posledovatelnosty');
for i:=1 to n do begin
read(a[i]);
end;
for i:=1 to n do begin
if a[i]=q then begin b:=i+1; for j:=b to n do begin s:=s+a[j]; <===============
end;
writeln('summa elementov posle chisla Q=',s);
end;
end;
for i:=1 to n do
begin if a[i]<0 then k:=k+1;
end;
if s=0 then
writeln('kolvo otric.chisel=',k);
end.





Казалось бы, что изменилось? А изменилось. Вот последовательность, которую дал преподаватель:

Кол-во элементов : 7.
Число q, с которым сравниваем = 15
а вот сама последовательность:
a[1]=8
a[2]=12
a[3]=15
a[4]=4
a[5]=15
a[6]=2
a[7]=1

и вместо положенных 22, программа выдала 2 ответа: 22 и 25. При чем в первом варианте программы ответ был один и верный - 22!!!!!
Я начал подробно смотреть решение. Разбивал эти циклы на два отдельных цикла - выдает ошибку.
Перемещал end'ы - безрезультатно.
Подскажите, что делать?
При чем, программу я писал сам, и при написании даже не думал, почему НЕ нужно менять букву счетчика. А препод заставил задуматься. Поможете?

Заранее спасибо.

Автор: volvo 25.12.2009 3:31

Во-первых, преподаватель совершенно прав. Попробуй откомпилировать свою первую программу на современном компиляторе (FPC/Delphi) - получишь ошибку, нельзя делать 2 вложенных цикла по одной переменной. Кстати, никто не гарантирует, что после окончания For переменная i будет равна последнему значению, так что тебе, можно сказать, повезло, что программа работала, да еще и работала правильно.

Я бы решал задачу вот так:

  i := 0;
repeat
inc(i);
if a[i] < 0 then k := k + 1
else
if a[i] = q then begin
inc(i);
while i <= n do begin
s := s + a[i]; inc(i);
end;
end;
until i > n;

if s = 0 then
writeln('kolvo otric.chisel=',k)
else
writeln('summa elementov posle chisla Q=',s);
, здесь не надо вводить новую переменную, поскольку используется не цикл For, а циклы While/Repeat. А в твоем случае... Хм. Ну, надо наверное выходить из внешнего цикла сразу после того, как найден первый элемент, равный Q, и сумма элементов, стоящих после него. Break в помощь...

Автор: smith 25.12.2009 5:03

Большое спасибо! Очень помогло!
Там правда с break не получится, ибо



if a[i]=q then brake;
b:=i+1



ошибка (выходит за границы массива).
Ну, в общем разобрался. Просто зациклился я на цикле for to=)
Спасибо что помогли разобраться.

Автор: Lapp 25.12.2009 10:41

Цитата(smith @ 25.12.2009 1:03) *
Просто зациклился я на цикле for to=)
smith, нет. Не просто зациклился. Перечитай слова volvo.

Если бы у тебя был бы цикл wile или repeat, и ты бы там как-то использовал собственным образом инкрименируемую переменную i с условиями - вот тогда ты может быть бы и просто зациклился. Тут же ошибка более грубая.

Никогда и ни при каких обстоятельствах не используй параметр цикла вторично внутри цикла! Табу.

Автор: volvo 25.12.2009 13:31

Кстати, в моем фрагменте кода есть небольшая ошибка, которая может привести к аварийному завершению программы (правда это практически нереально при заданных автором вопроса условиях). Вчера не заметил, потому как набирал программу прямо здесь. Сегодня - заметил...

smith, покажешь мне, где я накосячил, при каких условиях это проявится, и (главное) как это исправить? smile.gif