|
Главная | Правила | Регистрация | Дневники | Справка | Пользователи | Календарь | Поиск | Сообщения за день | Все разделы прочитаны |
|
Опции темы | Опции просмотра |
03.12.2013, 19:05 | #1 (permalink) |
Новичок
Регистрация: 03.12.2013
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
|
Помогите исправить, пожалуйста
Вот, что получилось: |
03.12.2013, 19:05 | |
Helpmaster
Member
Регистрация: 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) | |
Специалист
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
|
Цитата:
Тут есть одна тонкость. Вы применяете следующий алгоритм поиска максимума и минимума: объявляете таковыми первый элемент, а затем, начиная со второго, сравниваете элементы с 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; |
|
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) |
Специалист
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
|
|
Ads | |
Member
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
|
04.12.2013, 10:08 | #8 (permalink) |
Специалист
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
|
Ага. Ну теперь я из примера хоть понял, что значит "перевернуть" и что значит "поплавок".
Да, действительно, эта часть программы сделана неверно. Исправил. Кстати, переменная "а" не нужна вовсе - выбросил. И еще пожелание. С моей точки зрения, любое действие программиста должно быть осмысленным, в частности, присоединение модуля 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. |
04.12.2013, 10:23 | #9 (permalink) | |
Новичок
Регистрация: 03.12.2013
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
|
ага, это осталось еще от предыдущих неудачных попыток, я вчера убрала ее
Цитата:
Спасибо большое за помощь) было бы здорово, если бы все преподаватели так понятно объясняли, как вы) |
|
Ads | |
Member
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
|
Опции темы | |
Опции просмотра | |
|
|