• Добро пожаловать на компьютерный форум Tehnari.ru. Здесь разбираемся с проблемами ПК и ноутбуков: Windows, драйверы, «железо», сборка и апгрейд, софт и безопасность. Форум работает много лет, сейчас он переехал на новый движок, но старые темы и аккаунты мы постарались сохранить максимально аккуратно.

    Форум не связан с магазинами и сервисами – мы ничего не продаём и не даём «рекламу под видом совета». Отвечают обычные участники и модераторы, которые следят за порядком и качеством подсказок.

    Если вы у нас впервые, загляните на страницу о форуме и правила – там коротко описано, как задать вопрос так, чтобы быстро получить ответ. Чтобы создавать темы и писать сообщения, сначала зарегистрируйтесь, а затем войдите под своим логином.

    Не знаете, с чего начать? Создайте тему с описанием проблемы – подскажем и при необходимости перенесём её в подходящий раздел.
    Задать вопрос Новые сообщения Как правильно спросить
    Если пришли по старой ссылке со старого Tehnari.ru – вы на нужном месте, просто продолжайте обсуждение.

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

Стася

Ученик
Регистрация
3 Дек 2013
Сообщения
11
Реакции
0
Баллы
0
Помогите исправить, пожалуйста

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

Вот, что получилось:
 

Вложения

  • задание.webp
    задание.webp
    34.4 KB · Просмотры: 125
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:=Random(v_max-v_min + 1) + v_min;

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

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

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

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

If (vector < min) Then {если очередной элемент меньше} {текущего минимального}
Begin
min := vector; {то минимальным элементом}
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<max) and (vector>max_2) Then
Begin
max_2 := vector; {то максимальным элементом}
i_max_2 := i; {становится очередной элемент} {вектора}
End;

If (vector>min)and (vector<min_2) Then
Begin
min_2 := vector; {то минимальным элементом}
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:5);
WriteLn
End;
End.
 
Программа, которая у меня получилась то нормально работает, то вместо второго максимального по значению элемента находит просто максимальный( всю голову сломала уже
Ничего страшного, Стася, всё понятно, сейчас поправим.
Тут есть одна тонкость. Вы применяете следующий алгоритм поиска максимума и минимума: объявляете таковыми первый элемент, а затем, начиная со второго, сравниваете элементы с 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!!!
 
Спасибо огромное! Теперь понятно)
А можете еще вот этот момент посмотреть?

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;" тоже ошибка. Когда а без остатка делится - все вроде правильно переворачивается, а в других случаях - на своих местах остается
Как это исправить можно?
 
А можете еще вот этот момент посмотреть?
Увы, только завтра. Сейчас я выхожу из Сети. А пока был бы признателен, если бы Вы уточнили, что за алгоритм Вы применяете? Что за "поплавок"? Ссылку дайте или своими словами объясните.
 
До прошлой недели я с программированием не сталкивалась особо, поэтому по примеру пыталась сделать:
 

Вложения

  • пример.webp
    пример.webp
    36.9 KB · Просмотры: 76
А в моем задании нужно было между i_min_2 и i_max_2 перевернуть элементы
 
А в моем задании нужно было между 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.
 
Кстати, переменная "а" не нужна вовсе - выбросил.
ага, это осталось еще от предыдущих неудачных попыток, я вчера убрала ее

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

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