Технический форум

Технический форум (http://www.tehnari.ru/)
-   Помощь студентам (http://www.tehnari.ru/f41/)
-   -   Паскаль АВС. Задача с массивами (http://www.tehnari.ru/f41/t82217/)

Серёга_IV 14.12.2012 18:58

Паскаль АВС. Задача с массивами
 
Помогите решить задачу. Условие:
Поменять местами первое положительное число с последним отрицательным в одномерном массиве из целых чисел.

Менять местами желательно используя дополнительную переменную :tehnari_ru_942:

Я бы скинул вам свой вариант, но мне нельзя размещать ссылки, и по величине не подходит изображение.

Vladimir_S 14.12.2012 19:58

Вложений: 1
Цитата:

Сообщение от Серёга_IV (Сообщение 833396)
Помогите решить задачу.

Вообще-то с подобными пустяками уровня подготовительной группы детсада для умственно-отсталых я посылаю куда подале, ведь на чем же еще учиться (если, конечно, есть таковое намерение), как не на подобной ерунде? Но ладно, Вложение 110820. Получите. Но это, правда, Free Pascal. Вроде без разницы.
Код:

Const
 N=20;
Var
 A:Array[1..N] of Integer;
 i1,i2,i,D:Integer;
Begin
 Randomize;
 Writeln('Old array:');
 For i:=1 to N do
  begin
  A[i]:=10-Random(20);
  Write(A[i]:4);
  end;
 Writeln;
 i1:=1;
 If A[i1]<=0 then
  Repeat
  Inc(i1);
  Until (A[i1]>0) or (i1=N);
 i2:=N;
 If A[i2]>=0 then
  Repeat
  Dec(i2);
  Until (A[i2]<0) or (i2=1);
 If (A[i1]>0) and (A[i2]<0) then
  begin
  D:=A[i1];
  A[i1]:=A[i2];
  A[i2]:=D;
  writeln('New array:');
  for i:=1 to N do Write(A[i]:4);
  end
 else
 If A[i1]<=0 then
  Writeln('No positives!')
 else
 If (A[i2]>=0) then
  Writeln('No negatives!');
 Readln
End.


Серёга_IV 14.12.2012 20:36

Спасибо, я понимаю, что это для вас просто, но я 9 класс, и вот только месяц мы изучаем массивы.
Ещё раз спасибо.

Vladimir_S 14.12.2012 20:42

Цитата:

Сообщение от Серёга_IV (Сообщение 833459)
Спасибо, я понимаю, что это для вас просто, но я 9 класс, и вот только месяц мы изучаем массивы. Ещё раз спасибо.

О, тогда - приношу глубочайшие извинения. Всё нормально. Я-то думал - очередной студент-лоботряс семестр пробездельничал, а перед сессией спохватился. Я таких... как бы это... несколько недолюбливаю.
А Вам - успехов. Обращайтесь, если что - поможем.

Серёга_IV 14.12.2012 20:46

Мой вариант таков:
Program z_1;
Var g:array[1..10] of integer;
p,o,d,i:integer;
Begin
for i:= 1 to 10 do g[i]:=random (21)-10;
for i:= 1 to 10 do write(g[i],',');
writeln;
for i:= 1 to 10 do if g[i]>0 then i:=p;
for i:= 10 downto 1 do if g[i]<0 then i:=o;
d:=g[p];
g[p]:=g[o];
g[o]:=d;
for i:= 1 to 10 do write (g[i]:4);
End.

Скажите пожалуйста, в чём недочёт, не проходит по времени.

Vladimir_S 15.12.2012 09:38

Сергей, у Вас в программе две грубейших ошибки, одна техническая, вторая - смысловая. Обе они в строках:
Цитата:

Сообщение от Серёга_IV (Сообщение 833464)
for i:= 1 to 10 do if g[i]>0 then i:=p;
for i:= 10 downto 1 do if g[i]<0 then i:=o;

Давайте разбираться.
1. Вместо того, чтобы при выполнении условия присвоить переменным p и o значения переменной цикла i, Вы поступаете ровно наоборот: переменной цикла присваиваете значения p и o, изначально не заданные и, следовательно, по умолчанию нулевые. Результат: цикл летит в тар-тарары.
2. Это уже серьёзней. Ведь не зря в моей программе применен не for..to..do, а repeat..until. Сделано это отнюдь не по скудоумию моему, как Вы, очевидно, решили, а вот зачем: как только в первом цикле программа находит положительное число, а во втором - отрицательное, циклы необходимо прервать. Иначе перезапись будет продолжаться до конца, и в результате программа найдет ПОСЛЕДНЕЕ положительное и ПЕРВОЕ отрицательное числа. В принципе прерывание можно организовать и в циклах for..to..do, хотя я подобным стараюсь не пользоваться, так как полагаю такой стиль программирования изрядно дурным. Но, если угодно, то пожалуйста: вот исправленный вариант:
Код:

Var
 g:array[1..10] of integer;
 p,o,d,i:integer;
Begin
 Randomize;
 for i:= 1 to 10 do
  g[i]:=random (21)-10;
 for i:= 1 to 10 do write(g[i]:4);
 writeln;
 for i:= 1 to 10 do
  if g[i]>0 then
  begin
    p:=i;
    break;
  end;
 for i:= 10 downto 1 do
  if g[i]<0 then
  begin
    o:=i;
    break;
  end;
 d:=g[p];
 g[p]:=g[o];
 g[o]:=d;
 for i:= 1 to 10 do write (g[i]:4);
 readln
End.

В принципе, можно и без прерываний. Но тогда циклы надо пустить в обратную сторону: пусть положительное число ищет, начиная с КОНЦА, а отрицательное - с НАЧАЛА, перезаписывая найденные значения p и o. Тогда остановится на нужных. Это так:
Код:

Var
 g:array[1..10] of integer;
 p,o,d,i:integer;
Begin
 Randomize;
 for i:= 1 to 10 do
  g[i]:=random (21)-10;
 for i:= 1 to 10 do write(g[i]:4);
 writeln;
 for i:= 10 downto 1 do if g[i]>0 then p:=i;
 for i:= 1 to 10 do if g[i]<0 then o:=i;
 d:=g[p];
 g[p]:=g[o];
 g[o]:=d;
 for i:= 1 to 10 do write (g[i]:4);
 readln
End.

И еще. Вот Вы выбросили проверку наличия хоть одного положительного и хоть одного отрицательного элементов массива. Ну что же - дело Ваше, только мне кажется, лучше всё-таки предусмотреть ситуации, когда все члены массива оказываются либо положительными, либо отрицательными. Хотя бы во избежание каверзных вопросов учителя. Впрочем, как хотите.

Серёга_IV 15.12.2012 19:40

Спасибо, я понял. И по моему, всё таки, когда мы просматриваем элементы массива, компьютер находит первый элемент, соответствующий условию и запоминает именно его, а остальные не смотрит. при выполнении программы получилось именно так.
И я не в коем случае не думаю, что вы плохо знаете программирование. :tehnari_ru_942:

Серёга_IV 15.12.2012 19:55

Значит я исправил первую ошибку. И всё получилось отлично. Просто переменным присвоил значение индексов, а не наоборот, как было сначала.
На счёт нюансов с числами одинаковых знаков: спасибо за замечание, но пока мне это не обязательно.

Спасибо.

Vladimir_S 15.12.2012 20:03

Вложений: 1
Цитата:

Сообщение от Серёга_IV (Сообщение 833930)
Спасибо, я понял. И по моему, всё таки, когда мы просматриваем элементы массива, компьютер находит первый элемент, соответствующий условию и запоминает именно его, а остальные не смотрит. при выполнении программы получилось именно так.
И я не в коем случае не думаю, что вы плохо знаете программирование. :tehnari_ru_942:

Не, ну вот ведь Фома Неверующий!
Ладно. Запустил Вашу программу, исправив лишь присваивание значений o и p и добавив вывод этих параметров и соответствующих им элементов массивов на экран. Вот листинг:

Var g:array[1..10] of integer;
p,o,d,i:integer;
Begin
for i:= 1 to 10 do g[i]:=random (21)-10;
for i:= 1 to 10 do write(g[i]:4);
writeln;
for i:= 1 to 10 do if g[i]>0 then p:=i;
for i:= 10 downto 1 do if g[i]<0 then o:=i;
writeln('p= ',p:2,' g[p]= ',g[p]:3);
writeln('o= ',o:2,' g[o]= ',g[o]:3);
d:=g[p];
g[p]:=g[o];
g[o]:=d;
for i:= 1 to 10 do write (g[i]:4);
End.

А вот результат, полюбуйтесь:
Вложение 111085
И что, это, по-Вашему ПЕРВЫЙ положительный и ПОСЛЕДНИЙ отрицательный элементы? А по-моему, всё с точностью до наоборот. Что я Вам и пытался объяснить. Но, впрочем, если Вы обладаете магическим даром заставить компьютер считать не так, как предписано программой, а так, как хочется Вам - в добрый час! :D

P.S. Прошу прощения, изначально не тот рисунок вставил. Исправлено.

Серёга_IV 15.12.2012 22:33

Ну это всё моя невнимательность. Извиняюсь :)


Часовой пояс GMT +4, время: 08:07.

Powered by vBulletin® Version 4.5.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.