Технический форум
Вернуться   Технический форум > Программирование > Форум программистов > Delphi, Kylix and Pascal


Ответ
 
Опции темы Опции просмотра
Старый 03.12.2013, 19:05   #1 (permalink)
Стася
Новичок
 
Регистрация: 03.12.2013
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию Помогите исправить, пожалуйста

Программа, которая у меня получилась то нормально работает, то вместо второго максимального по значению элемента находит просто максимальный( всю голову сломала уже

Вот, что получилось:
Миниатюры
caaeaiea.jpg  
Стася вне форума   Ответить с цитированием

Старый 03.12.2013, 19:05
Helpmaster
Member
 
Аватар для Helpmaster
 
Регистрация: 08.03.2016
Сообщений: 0

Это ссылки на схожие темы, настоятельно рекомендую прочитать

Помогите исправить ошибку, пожалуйста
Помогите исправить ошибку
Помогите исправить код

Старый 03.12.2013, 19:06   #2 (permalink)
Стася
Новичок
 
Регистрация: 03.12.2013
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Program Variant_5;
Uses Crt;
Const n = 10; {задание размера вектора именованной константой}

Var i, v_min, v_max,i_max, max,i_min, min, i_max_2, max_2, i_min_2, min_2, k, m, a, i1, i2 : Integer;
vector : Array [1..n] Of Integer;

Begin

Randomize; {запуск генератора случайных чисел}
WriteLn('Задайте диапазон случайных чисел');
Write('v_min=');
ReadLn(v_min);
Write('v_max=');
ReadLn(v_max);

For i:=1 To n Do {заполнение вектора случайными числами}
vector[i]:=Random(v_max-v_min + 1) + v_min;

WriteLn;
WriteLn('Исходный вектор:');
For i:=1 To n Do {вывод на экран исходного вектора}
Write(vector[i]:5);
WriteLn;

max:= vector[1]; {пока макс элемент - первый элемент вектора}
i_max:= 1;
min:= vector[1]; {пока мин элемент - первый элемент вектора}
i_min:= 1;

For i:=2 To n Do {поиск начинаем со второго элемента}
Begin

If (vector[i] > max) Then {если очередной элемент больше} {текущего максимального}
Begin
max := vector[i]; {то максимальным элементом}
i_max := i; {становится очередной элемент} {вектора}
End;

If (vector[i] < min) Then {если очередной элемент меньше} {текущего минимального}
Begin
min := vector[i]; {то минимальным элементом}
i_min := i; {становится очередной элемент} {вектора}
End;

End;


max_2:= vector[1];
i_max_2:= 1;
min_2:= vector[1];
i_min_2:= 1;

For i:=2 To n Do
Begin

If (vector[i]<max) and (vector[i]>max_2) Then
Begin
max_2 := vector[i]; {то максимальным элементом}
i_max_2 := i; {становится очередной элемент} {вектора}
End;

If (vector[i]>min)and (vector[i]<min_2) Then
Begin
min_2 := vector[i]; {то минимальным элементом}
i_min_2 := i; {становится очередной элемент} {вектора}
End;

End;

WriteLn;
WriteLn('max_2=', max_2, ' i_max_2=', i_max_2);
WriteLn('min_2=', min_2, ' i_min_2=', i_min_2);

If min=max then write('Решений нет-все элементы равны между собой')
else
begin
If i_min_2<i_max_2 then
Begin
i1:=i_min_2;
i2:=i_max_2;
End
Else
Begin
i2:=i_min_2;
i1:=i_max_2;
End;

a:=n-i2;
m:=(i2-i1) Div 2;
For i:=i1 To m Do
Begin
k:= vector[i1+i];
vector[i1+i]:=vector[i2-i] ;
vector[i2-i]:=k;
End;

WriteLn;
WriteLn('Полученный вектор:');
For i:=1 To n Do {вывод на экран полученного вектора}
Write(vector[i]:5);
WriteLn
End;
End.
Стася вне форума   Ответить с цитированием
Старый 03.12.2013, 20:26   #3 (permalink)
Vladimir_S
Специалист
 
Аватар для Vladimir_S
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 25,358
Сказал(а) спасибо: 245
Поблагодарили 468 раз(а) в 148 сообщениях
Репутация: 80483
По умолчанию

Цитата:
Сообщение от Стася Посмотреть сообщение
Программа, которая у меня получилась то нормально работает, то вместо второго максимального по значению элемента находит просто максимальный( всю голову сломала уже
Ничего страшного, Стася, всё понятно, сейчас поправим.
Тут есть одна тонкость. Вы применяете следующий алгоритм поиска максимума и минимума: объявляете таковыми первый элемент, а затем, начиная со второго, сравниваете элементы с max и min, и если кто-то из них больше max или меньше min, то он и становится новым max (min). Так вот, пока дело касается ПЕРВЫХ максимумов, это правильно, а вот со вторыми уже может возникнуть ошибка. Представьте себе, что самым максимальным оказался ПЕРВЫЙ ПО СЧЕТУ элемент. И что тогда произойдёт? Вы объявляете его вторым максимумом (max_2), а потом, сравнивая с ним все прочие элементы, получаете невыполнение условия переприсвоения значения max_2 и, следовательно, он так и остается якобы вторым по величине.
Избежать этой ситуации можно, например, так:
Код:
 max_2:= min;
 min_2:= max;

 For i:=1 To n Do
  Begin
   If (vector[i]<max) and (vector[i]>max_2) Then
    Begin
     max_2 := vector[i];
     i_max_2 := i;
    End;
   If (vector[i]>min)and (vector[i]<min_2) Then
    Begin
     min_2 := vector[i];
     i_min_2 := i;
    End;
  End;
Обратите внимание: перебор начинается с i=1!!!
__________________
With Mozilla Firefox - straight to communism!
Vladimir_S на форуме   Ответить с цитированием
Старый 03.12.2013, 20:50   #4 (permalink)
Стася
Новичок
 
Регистрация: 03.12.2013
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Спасибо огромное! Теперь понятно)
А можете еще вот этот момент посмотреть?

begin
If i_min_2<i_max_2 then
Begin
i1:=i_min_2;
i2:=i_max_2;
End
Else
Begin
i2:=i_min_2;
i1:=i_max_2;
End;

a:=i2-i1;
m:= a Div 2;
For i:=i1 To m Do
Begin
k:= vector[i1+i];
vector[i1+i]:=vector[i2-i] ;
vector[i2-i]:=k;
End;
Похоже,где "m:= a Div 2;" тоже ошибка. Когда а без остатка делится - все вроде правильно переворачивается, а в других случаях - на своих местах остается
Как это исправить можно?
Стася вне форума   Ответить с цитированием
Старый 03.12.2013, 20:58   #5 (permalink)
Vladimir_S
Специалист
 
Аватар для Vladimir_S
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 25,358
Сказал(а) спасибо: 245
Поблагодарили 468 раз(а) в 148 сообщениях
Репутация: 80483
По умолчанию

Цитата:
Сообщение от Стася Посмотреть сообщение
А можете еще вот этот момент посмотреть?
Увы, только завтра. Сейчас я выхожу из Сети. А пока был бы признателен, если бы Вы уточнили, что за алгоритм Вы применяете? Что за "поплавок"? Ссылку дайте или своими словами объясните.
__________________
With Mozilla Firefox - straight to communism!
Vladimir_S на форуме   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Старый 03.12.2013, 21:05   #6 (permalink)
Стася
Новичок
 
Регистрация: 03.12.2013
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

До прошлой недели я с программированием не сталкивалась особо, поэтому по примеру пыталась сделать:
Миниатюры
idheiadh.png  
Стася вне форума   Ответить с цитированием
Старый 03.12.2013, 21:07   #7 (permalink)
Стася
Новичок
 
Регистрация: 03.12.2013
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

А в моем задании нужно было между i_min_2 и i_max_2 перевернуть элементы
Стася вне форума   Ответить с цитированием
Старый 04.12.2013, 10:08   #8 (permalink)
Vladimir_S
Специалист
 
Аватар для Vladimir_S
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 25,358
Сказал(а) спасибо: 245
Поблагодарили 468 раз(а) в 148 сообщениях
Репутация: 80483
По умолчанию

Цитата:
Сообщение от Стася Посмотреть сообщение
А в моем задании нужно было между i_min_2 и i_max_2 перевернуть элементы
Ага. Ну теперь я из примера хоть понял, что значит "перевернуть" и что значит "поплавок".
Да, действительно, эта часть программы сделана неверно. Исправил. Кстати, переменная "а" не нужна вовсе - выбросил.
И еще пожелание. С моей точки зрения, любое действие программиста должно быть осмысленным, в частности, присоединение модуля CRT ("uses CRT") следует делать, если Вы реально используете CRT-команды, а в Вашей программе таковые отсутствуют. К сожалению, правда, встречаются горе-преподаватели, которые требуют, чтобы студенты всегда подключали в своих программах этот самый CRT - типа "на всякий случай". Моя бы воля - я бы таких преподов гнал в шею.
Ну ладно, это, как говорится, лирика. Ниже я выложил отлаженную программу. Извините за переход на английский - просто с использованием кириллицы у меня проблемы в плане кодировки, поэтому стараюсь без крайней нужды ее не задействовать. Но это Вы поправите легко. И еще: если не нужно, то в конце оператор Readln можно удалить.
И еще. Увеличил длину массива до 20, потому что при n=10 никак было не попасть в ситуацию, когда i1 и i2 сильно разведены: то они соседние, то через один, а в этом случае "поплавок" не работает и было невозможно проверить.
Код:
Const
 n = 20;

Var
 i, v_min, v_max,i_max, max,i_min, min, i_max_2,
 max_2, i_min_2, min_2, k, m, i1, i2 : Integer;
 vector : Array [1..n] Of Integer;

Begin

 Randomize;
 WriteLn('Random numbers range:');
 Write('v_min=');
 ReadLn(v_min);
 Write('v_max=');
 ReadLn(v_max);

 For i:=1 to n do
  vector[i]:=Random(v_max-v_min + 1) + v_min;

 WriteLn;
 WriteLn('Initial vector:');
 For i:=1 To n Do
  Write(vector[i]:5);
 WriteLn;

 max:= vector[1];
 i_max:= 1;
 min:= vector[1];
 i_min:= 1;

 For i:=2 To n Do
  Begin
   If (vector[i] > max) Then
    Begin
     max := vector[i];
     i_max := i;
    End;

   If (vector[i] < min) Then
    Begin
     min := vector[i];
     i_min := i;
    End;
  End;


 max_2:= min;
 min_2:= max;

 For i:=1 To n Do
  Begin
   If (vector[i]<max) and (vector[i]>max_2) Then
    Begin
     max_2 := vector[i];
     i_max_2 := i;
    End;

   If (vector[i]>min) and (vector[i]<min_2) Then
    Begin
     min_2 := vector[i];
     i_min_2 := i;
    End;
  End;

 WriteLn;
 WriteLn('max_2=', max_2, ' i_max_2=', i_max_2);
 WriteLn('min_2=', min_2, ' i_min_2=', i_min_2);

 If min=max then
  writeln('No solution: all elements are equal')
 else
  begin
   If i_min_2<i_max_2 then
    Begin
     i1:=i_min_2;
     i2:=i_max_2;
    End
   Else
    Begin
     i2:=i_min_2;
     i1:=i_max_2;
    End;

   m:=(i2-i1) Div 2;
   For i:=1 To m Do
    Begin
     k:= vector[i1+i];
     vector[i1+i]:=vector[i2-i] ;
     vector[i2-i]:=k;
    End;

   WriteLn;
   WriteLn('Final vector:');
   For i:=1 To n Do
    Write(vector[i]:5);
   WriteLn
  end;
 Readln
End.
__________________
With Mozilla Firefox - straight to communism!
Vladimir_S на форуме   Ответить с цитированием
Старый 04.12.2013, 10:23   #9 (permalink)
Стася
Новичок
 
Регистрация: 03.12.2013
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Цитата:
Сообщение от Vladimir_S Посмотреть сообщение
Кстати, переменная "а" не нужна вовсе - выбросил.
ага, это осталось еще от предыдущих неудачных попыток, я вчера убрала ее

Цитата:
Сообщение от Vladimir_S Посмотреть сообщение
правда, встречаются горе-преподаватели, которые требуют, чтобы студенты всегда подключали в своих программах этот самый CRT - типа "на всякий случай"
У нас как раз такой случай, просят вставлять CRT - все-таки программирование не является профильным предметом у нас и дается в очень сжатые сроки

Спасибо большое за помощь) было бы здорово, если бы все преподаватели так понятно объясняли, как вы)
Стася вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.




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

Powered by vBulletin® Version 6.2.5.
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.