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

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

Форум «Всё о Паскале» _ Задачи _ Одномерный массив.

Автор: **star** 4.11.2009 21:51

В массивее А = ( а1, а2, . . . аn ) все положительные элементы ,
начиная со второго положительного, отправить в хвост массива .
( Новый массив не создавать ).

Есть программа,но почему-то не всегда работает правильно...

Program Lab;
Uses crt;

type arr=array[1..15] of integer;
var a:arr;
p,k,i,j,n:integer;

begin
clrscr;
writeln;
writeln('Dan odnomernij massiv celih chisel');
writeln('W massiwe wse pologitelnie element,nachinaja so wtorogo, otprawit w hwost massiwa');
writeln;
{$R+}
n:=15;
randomize;
writeln('Ishodnij massiv:');
for i:=1 to n do
begin
a[i]:=-20+random(41);
write(a[i]:4);
end;
writeln;
k:=0;
p:=0;
for i:=1 to n do
begin
if a[i]>=0 then
begin
k:=k+1;
if k>1 then
begin
p:=a[i];
for j:=i to n do
if j<>n then
a[j]:=a[j+1]
else
a[j]:=p;
i:=i-1;
end;
end;
end;
Writeln('Resultat obrabotki');
for i:=1 to n do
write(a[i]:4);
readln;
{$R-}
end.


Автор: volvo 4.11.2009 22:01

Цитата
for i:=1 to n do
begin
if a[i]>=0 then
begin
k:=k+1;
if k>1 then
begin
p:=a[i];
for j:=i to n do
if j<>n then
a[j]:=a[j+1]
else
a[j]:=p;
i:=i-1; { <------ !!! Вот на эту строку посмотри !!! }
end;
end;
end;
, и больше никогда так не делай. Нельзя менять переменную I внутри цикла. Это делает сам компилятор. Если тебе обязательно надо контролировать i самостоятельно - есть другие циклы: while и repeat...

Автор: **star** 4.11.2009 22:38

Посмотрела еще раз, но не очень поняла в чем ошибка...

Автор: Lapp 5.11.2009 7:07

Цитата(**star** @ 4.11.2009 18:38) *
Посмотрела еще раз, но не очень поняла в чем ошибка...
Тебе же сказали.. )) Никогда не изменяй переменную цикла for внутри цикла!
Вообще, в ТР в большинстве случаев (хотя это крайне не рекомендуется и результат не гарантируется) это все же проходит (в отличие от более новых компиляторов, например FPC, который тебе просто не пропустит компиляцию в этом случае). Но, как правило, это усложняет логику настолько, что очень легко запутаться. Именно это и произошло в твоем случае. Если возникает желание изменить параметр цикла - значит, нужно ввести еще одну переменную и работать с ней (я ввел переменную m). Либо заменить цикл на repeat or while (см. ответ volvo), но в этом случае максимум внимания нужно уделить отслеживанию границ (в чем ты и прокололась).
{$R+}
type
arr=array[1..15] of integer;

var
a:arr;
p,k,i,j,m,n:integer;

begin
writeln;
writeln('Dan odnomernij massiv celih chisel');
writeln('W massiwe wse pologitelnie element,nachinaja so wtorogo, otprawit w hwost massiwa');
writeln;
n:=15;
randomize;
writeln('Ishodnij massiv:');
for i:=1 to n do begin
a[i]:=-20+random(41);
write(a[i]:4)
end;
writeln;
k:=0;
p:=0;
m:=1;
for i:=1 to n do begin
if a[m]>0 then begin
k:=k+1;
if k>1 then begin
p:=a[m];
for j:=m to n-1 do a[j]:=a[j+1];
a[n]:=p
end
else Inc(m)
end
else Inc(m)
end;
Writeln('Resultat obrabotki');
for i:=1 to n do write(a[i]:4);
readln
end.

Совет на другую тему: отключи использование символов табуляции в опциях редактора - экономия на этом копеечная, а вреда (при попытке редактирования в другом редакторе) достаточно. Заботься о тех, кто тебе помогает)).

Еще я выкинул всякую дрянь, типа clrscr. Сохраниение результатов предыдушего запуска программы при отладке - очень полезная штука. И вообще непонятно, зачем его чистить. Это имеет смысл делать, если только твой вывод позиционный и использует весь экран.

И еще непонятно, зачем ты отключала range check в конце. При отладке лучше либо включить опцию проверки в меню среды, либо иметь ее в начале программы. Отключать же проверку можно только на окончательно проверенном варианте, если время исполнения существенно.