Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] Pascal от новичка (ошибку не вижу) (http://forum.oszone.net/showthread.php?t=222004)

lenaustkz84 02-12-2011 13:13 1807935

Pascal от новичка (ошибку не вижу)
 
Здравствуйте!

Я только начала изучать Pascal.
Дело очень интересное:)

Но вот моя задача: Мне нужно составить простую программу
на нахождение максимального и минимального значения
из N введенных чисел.

Вроде бы все сделала правильно. И ошибок компилятор не выдает.
Но работает программа не совсем верно.

Максимальное значение определяет безошибочно.

Но минимальное значение находит верно лишь в том случае,
если число отрицательное.

Допустим из 5 введенных чисел: 1 2 -3 7 5
Программа правильно выдает:
max=7
min=-3

Если ввести числа так: 1 2 3 4 5
То программа работает не правильно:
max=5
min=0

Кстати, условие такое, что нужно использовать
конструкцию repeat...until.

Посмотрите, пожалуйста, мой код, наверное, что-то нужно добавить?

Код:

{Программа для определения максимального  и минимального  значения из N введенных чисел}
program max_i_min_iz_N; 

uses crt;

var N,min,max,a,i,m:integer;

BEGIN

  clrscr;
      repeat
          write('Введите любую цифру: '); readln(N); writeln();
          write('Введите ',N,' чисел(-а) через пробел: ');

          i:=1; max:=0; min:=0; a:=0; m:=0;

              repeat
                read(a);

                if (a>max) then max:=a else max:=max;
                if (a<min) then min:=a else min:=min;

                i:=i+1; a:=0;
              until(i>N);

        writeln();
        writeln('max=',max);
        writeln('min=',min);

        writeln();
        writeln('Для продолжения программы нажмите цифру 1');
        writeln('Для завершения программы нажмите цифру 2');
        writeln();
        readln(m);
        writeln();

        until(m=2);
END.


CyberDaemon 02-12-2011 13:42 1807944

Цитата:

Цитата lenaustkz84
Максимальное значение определяет безошибочно. »

А если ввести
-1 -2 -3 -4 -5? ;)
Ошибка тут:
Код:

max:=0; min:=0;
С чего бы вдруг максимуму и минимуму быть равным нулю?

Hector 02-12-2011 13:49 1807949

lenaustkz84, ошибка в изначальном присвоении min:=0. у тебя выходит 0 всегда меньше положительного числа, т. е. условие a<min при положительном а никогда не выполнится.

и для решения этой задачи лучше использовать массивы

CyberDaemon 02-12-2011 14:01 1807957

Цитата:

Цитата Hector
и для решения этой задачи лучше использовать массивы »

Почему?

lenaustkz84 02-12-2011 14:01 1807958

Убрала из кода
Цитата:

Цитата lenaustkz84
max:=0; min:=0 »

все равно программа работает так же не верно.

Цитата:

Цитата CyberDaemon
А если ввести
-1 -2 -3 -4 -5? »

CyberDaemon, после того, как убарала из кода
max:=0; min:=0;
ввела числа -1 -2 -3 -4 -5.

Тогда получается так:
max=0
min=-5

CyberDaemon 02-12-2011 14:11 1807964

Все верно, простым убиранием обнуления преременных задачу не решить.
Думай, думай!
1) -1 -2 -3 -4
2) 1 2 3 4
3) 1 1 2 2
спойлер-подсказка

3) 1 1 1 1
4) -1 -1 -1 -1
если уж совсем туго, то

максимуму и минимуму сначала нужно присвоить значение первого введенного числа.
А потом уже сравнивать все последующие числа.

Hector 02-12-2011 14:15 1807965

CyberDaemon, imho удобней

lenaustkz84 02-12-2011 14:20 1807967

CyberDaemon, ну вот я так и сделала уже.
Добавила еще две переменных.
Но мне код не совсем нравиться.
Хотелось как-то в одной ячейке записывать и значения сравнивать с max и min.
Не хотелось еще задействовать две штуки дополнительно.
Хотя может и нормальный код...
Я еще мало в этом разбираюсь :)

Код:

{Программа для определения максимального  и минимального  значения
из N введенных чисел}
program max_i_min_iz_N;

uses crt;

var N,min,max,a,b,c,i,m:integer;

BEGIN
      clrscr;
        repeat
          write('Введите любую цифру: '); readln(N); writeln();
          write('Введите ',N,' чисел(-а) через пробел: ');
                read(a,b);

                if (a>b) then
                    begin max:=a; min:=b; end
                else begin max:=b; min:=a; end;

              i:=3;

              repeat
                read(c);

                    if(c>max) then max:=c else max:=max;
                    if(c<min) then min:=c else min:=min;

                    i:=i+1; c:=0;

              until(i>N);

          writeln();
          writeln('max=',max);
          writeln('min=',min);
          writeln();
     
      writeln('Для продолжения программы нажмите цифру 1');
      writeln('Для завершения программы нажмите цифру 2');
      writeln();
      readln(m);
      writeln();

        until(m=2);
END.

Новый код работает без ошибок.
С вводом любых значений, и положительных, и отрицательных.

CyberDaemon 02-12-2011 14:26 1807971

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

lenaustkz84, маньячно :)
И как отработает прога, если в ответ на
"write('Введите любую цифру: '); readln(N); writeln();"
ввести "1"?

lenaustkz84 02-12-2011 14:46 1807984

Ммм... ёлки-палки... только обрадовалась...
Если ввести 1, то... приходиться ввоить 3 значения, из которых программа без ошибки выбирает min и max.
То есть работает не с одним значением, как это нужно, а с тремя.
Это, наверное, потому что я задала i:=3;
Или нет. Наверное, потому что у меня изначально должно сравниваться 3 переменных, иначе программа не работает.

Кстати, для двойки такая же проблема.
Наверное, я сейчас добавлю отдельные операторы именно для значения 1 и 2.
Только, даже если будет работать, вообще муть какая-то получиться, наверное... :o

CyberDaemon 02-12-2011 15:00 1807997

Именно.
спрятал решение

Не надо вводить сначала два числа, а потом еще настойчиво ждать третьего.
Нужно просто после ввода первого из чисел - присвоить его и максимуму и минимуму, т.е. max=min=первое введенное число. Одна дополнительная строчка в первом варианте кода. При первом прогоне цикла инициализировать обе переменные введеным числом.

А еще можно поступить маньячно - какой там предел у типа integer? От -32768 до 32767?
Тогда в первом варианте вместо min:=0; max:=0; пишем max:=-32768; min:=32767 - тоже сработает - ибо любое введенное допустимое для integer число окачется внутри этих пределов :lol:


Цитата:

Цитата lenaustkz84
Наверное, я сейчас добавлю отдельные операторы именно для значения 1 и 2. »

Так и подмывает стереть мое сообщение, чтобы посмотреть, насколько монструозно можно решить задачку. Хотя, в плане обучения программированию - даже монстр полезен. Решено - не сотру, но спрячу :)

lenaustkz84 02-12-2011 15:23 1808009

Вот новый код. Теперь, наверное, точно все работает.
И для двойки. И для единицы.
Вот как бы только написать его по-красивее? :)
А то уж больно он мне не кажется таким, как надо.

Код:

{Программа для определения максимального  и минимального  значения
 из N введенных чисел}
program max_i_min_iz_N;

uses crt;

var N,min,max,a,b,c,i,m:integer;

BEGIN
      clrscr;
        repeat
          write('Введите любую цифру: '); readln(N); writeln();
          write('Введите ',N,' чисел(-а) через пробел: ');

          case N of
 
          1 : begin read(a); max:=a; writeln(); writeln('max=',max); end;

          2 : begin read(a,b);
                  if (a>b) then
                    begin max:=a; min:=b; end
                  else begin max:=b; min:=a; end;
                    writeln();
                    writeln('max=',max);
                    writeln('min=',min);
              end;

          else
            begin
                read(a,b);

                if (a>b) then
                    begin max:=a; min:=b; end
                    else begin max:=b; min:=a; end;

              i:=3;

              repeat
                read(c);

                if(c>max) then max:=c else max:=max;
                if(c<min) then min:=c else min:=min;

                i:=i+1; c:=0;
            until(i>N);

          writeln();
          writeln('max=',max);
          writeln('min=',min);

          end; {end else case}

        end; {end case}

        writeln();
        writeln('Для продолжения программы нажмите цифру 1');
        writeln('Для завершения программы нажмите цифру 2');
        writeln();
        readln(m);
        writeln();
    until(m=2);
END.


lxa85 02-12-2011 15:24 1808010

lenaustkz84,
Цитата:

Цитата lenaustkz84
Код:

i:=3;
repeat
 read(c);
if(c>max) then max:=c else max:=max;
 if(c<min) then min:=c else min:=min;
i:=i+1; c:=0;
until(i>N);

»


подожди, а здесь то что выполняется? :) Почему условия выхода из цикла такие странные?
i уже равно 3, хотя цифры вводить мы и не начинали. И как правильно указал CyberDaemon, min, max, еще не определены, а мы уже сравниваем с ними вводимое число.
----
Общая реплика: lenaustkz84, молодец, старайся, думай. :) Такие темы приятно читать и приятно помогать. :)

Все что вверху, уже не в счет!


Цитата:

Цитата lenaustkz84
Код:

begin
 read(a,b);
if (a>b) then
 begin max:=a; min:=b; end
 else begin max:=b; min:=a; end;
i:=3;
repeat
 read(c);
if(c>max) then max:=c else max:=max;
 if(c<min) then min:=c else min:=min;
i:=i+1; c:=0;
 until(i>N); »


Это хорошо, только напиши еще проще. У тебя уже изначально известно, что переменных больше двух. Соотв. первый if (a>b) не понятен (как следствие не нужен).
Попробуй переписать с использованием цикла for или чуть-исправить repeat until.
спойлер, не подглядывать :)

begin
read(c);
max:=c;
min:=c;
i:=1;
repeat
i:=i+1;
read(c);
if(c>max) then max:=c;
if(c<min) then min:=c;
until(i>=N);

lenaustkz84 02-12-2011 15:25 1808014

CyberDaemon, загляну теперь в Ваше решение :)

lxa85, как раз в том отрывке кода уже все работает. Только i:=3; потому что это уже третяя переменная, которую начинает сравнивать программа. А предыдущие две - это были сравнения 1 и 2. Если ставить i:=1; то нужно дописывать еще по два значения. Например, нужно найти max и min из 7 значений. Тогда приходиться вводить не 7, а 9 значений. Чтобы убрать эту ошибку, я присвоила переменной i значение 3. Ну вот, что-то такое постаралась объяснить :)

CyberDaemon, по Вашему объяснению кажется все так просто :)
Как же я сама не догадалась?
Напишу программку заново :)

lxa85, сейчас пишу по новому :) Покажу, что получилось :)

lenaustkz84 03-12-2011 10:20 1808447

CyberDaemon, lxa85, спасибо Вам за советы :)
Вот заново написала код.
Опять не слишком им довольна :not-me:
Но думаю, уже лучше, чем было.
Не нравиться этот i:=2;
Без этого условия приходиться вводить на одно значение больше.
Как, по Вашему мнению, уже лучше?
Или тоже сплошной монстр :)

Код:

{Программа для определения максимального  и минимального
значения из N введенных чисел}
program max_i_min_iz_N;
    uses crt;
    var N,min,max,a,i,m:integer;

    BEGIN
      clrscr;

        repeat

              i:=2;

              write('Введите любую цифру: '); readln(N); writeln();
              write('Введите ',N,' чисел(-а) через пробел: ');

                read(a);

                max:=a;
                min:=a;

            repeat
                read(a);
                if(a>max)then max:=a else max:=max;
                if(a<min)then min:=a else min:=min;
                i:=i+1;
            until(i>N);

        writeln();
        writeln('max=',max);
        writeln('min=',min);
        writeln();
       
      writeln('Для продолжения программы нажмите цифру 1');
      writeln('Для завершения программы нажмите цифру 2'); writeln();
      readln(m);
      writeln();
  until(m=2);
END.

Радует только то, что получилось убрать две лишние переменные b и c, и то, что убрала case.
И то, что программа работает во всех случаях... кроме одного...

Если здесь
Код:

write('Введите ',N,' чисел(-а) через пробел: '); read(a);
ввести значение 1, то программа все равно ждет ввода еще одного значения.

Наверное, потому, что у меня считывание переменной a все таки прописано в программе два раза?

При этом я пробовала оставлять только одно считывание переменной двумя вариантами.

Вариант 1

Код:

write('Введите любую цифру: '); readln(N); writeln();
                write('Введите ',N,' чисел(-а) через пробел: ');

                    i:=1;

                    max:=a;
                    min:=a;

                repeat

                  read(a);

                  if(a>max)then max:=a else max:=max;
                  if(a<min)then min:=a else min:=min;

                  i:=i+1;

              until(i>N);

Вариант 1: Переменной i тогда присваиваю 1 и дополнительного значения вводить не надо, в этом плане цикл работает правильно. Но находит из введенных значений правильно только максимальное число. Минимальному присваивает 0. Интересно то, что, если программу не закрыть, а продолжить дальше, то тогда программа начинает находить минимальное и максимальное число правильно. Но не из только что введенных значений, а из всех значений, которые были введены. Наверное, не понятно объясняю. Лучше картинку покажу :)



Вариант 2

Код:

write('Введите любую цифру: '); readln(N); writeln();
                write('Введите ',N,' чисел(-а) через пробел: ');

                i:=1;
                read(a);

                    max:=a;
                    min:=a;

                repeat

                  if(a>max)then max:=a else max:=max;
                  if(a<min)then min:=a else min:=min;

                  i:=i+1;

              until(i>N);

Вариант 2: здесь программа присваивает первое значение и max, и min, и следующие значения не сравнивает. При этом цикл на повторение программы не срабатывает. Программа просто закрывается и все. В приниципе, понятно, почему не сравнивает значения, ведь в следующем цикле учавствует только одно и то же значение переменной а, которое было введено первым. А вот почему тогда программа закрывается сама, не считывая переменную m?

В общем так вот...

lenaustkz84 03-12-2011 14:59 1808527

Вот еще по совету lxa85 попробовала написать код с применением FOR.
Что-то тоже не совсем правильно получается.
Нужно вводить больше значений для сравнения, чем требуется.

Код:

{Программа для определения максимального
и минимального  значения из N введенных чисел}

program max_i_min_iz_N_for;
    uses crt;
    var N,min,max,a,i,m:integer;

    BEGIN

      clrscr;

        repeat
              write('Введите любую цифру: '); readln(N); writeln();
              write('Введите ',N,' чисел(-а) через пробел: ');
                  read(a);
                  max:=a;
                  min:=a;

              for i:=1 to N do
              begin
                  readln(a);
                  if(a>max)then max:=a else max:=max;
                  if(a<min)then min:=a else min:=min;
              end;

          writeln();
          writeln('max=',max);
          writeln('min=',min);
          writeln();

          writeln('Для продолжения программы нажмите цифру 1');
          writeln('Для завершения программы нажмите цифру 2'); writeln();
          readln(m);
          writeln();

    until(m=2);
END.



Я уже достала Вас своими вопросами и кодами, наверное.

Но вообще стукаюсь глазами и не вижу, что делаю не так.

Не сочтите за труд, подскажите, где я ошибаюсь.

lxa85 03-12-2011 15:42 1808541

lenaustkz84, а почему ты от case отказалась? Он был вполне не дурен и к месту.
Пусть код будет чуть длиннее, ничего страшного. В условиях про универсальную формулу ничего не сказано. Докажи пользу от использования case и ты будешь молодец.
Дам тебе еще времени помучиться, а завтра напишу свой вариант решения. :)

P.S.
Защита от дурака: Ты уверена, что тебе введут положительную переменную N ? :modesty:

lenaustkz84 03-12-2011 20:48 1808670

Вот и я думала тоже про отрицательное число N и про ноль.
Но "успокоила" себя тем, что никто и не подумает вводить
такие цифры, ведь логично их не вводить.

Но замечание Ваше учла:)
И согласна. Все таки правильно поставить "защиту от дурака" :)

Сначала хотела с while, но тогда нунжно дважды прописывать
предложение ввода переменной N и ее считывание.
Мне показалось это не удобным.

Вот так было вначале:

Код:

write('Введите любое положительное число: '); readln(N); writeln();
    while (N<=0) do
          begin
            write('Введите любое положительное число: '); readln(N); writeln();
          end;

Потом решила сделать так:

Код:

repeat
    write('Введите любое положительное число: '); readln(N); writeln();
until(N>0);

С repeat...until удобно оказалось это сделать. Ничего дважды прописывать не надо.

lxa85, спасибо за совет :)
Посижу еще над программкой, подумаю :)

lxa85 04-12-2011 21:15 1809231

Как и обещал, привожу вариант решения в моей доработке.
Решение разумеется
свернуто

Код:

{Программа для определения максимального
и минимального  значения из N введенных чисел}

program max_i_min_iz_N_for;
    uses crt;
    var N,min,max,a,i:integer;

    BEGIN
      clrscr;
        repeat
              write('Введите натурально число N: '); readln(N); writeln();
                          if N>0 then begin
                                case N of
                                        1: begin
                                                        write('Введите ',N,' чисел(-а) через пробел: ');
                                                        read(a);
                                                        max:=a;
                                                        min:=a;
                                                end; //case 1
                                        2: begin
                                                        write('Введите ',N,' чисел(-а) через пробел: ');
                                                        read(a);
                                                        read(max);
                                                        if a<max then min:=a
                                                                else begin
                                                                        min:=max;
                                                                max:=a;
                                                        end;// if a<max
                                                end;// case 2       
                                        else: begin
                                                        write('Введите ',N,' чисел(-а) через пробел: ');
                                                        read(a);
                                                        max:=a;
                                                        min:=a;
                                                        for i:= 2 to N do begin
                                                                read(a)
                                                                if a>max then max:=a;
                                                                if a<min then min:=a;
                                                        end; // for i:= 2 to N
                                                end;// case else               
                                        end; //case N of
                                       
                                        // вывод результатов
                                        writeln();
                                        writeln('max=',max);
                                        writeln('min=',min);
                                        writeln();
                                       
                                        end // if N>0 then
                                else
                                        begin
                                                write('К сожалению, введеное число ',N,' не является натуральным');
                                        end; // if N>0


          writeln('Для продолжения программы введите цифру 1 и нажмите Enter');
          writeln('Для завершения программы введите цифру 2 и нажмите Enter');
                  writeln();
          readln(a);
          writeln(); // ?
    until(a=2);
END.


Компилятора под руками нет, "на глаз" ошибок нет.
P.S. у меня табуляция в notepad++ настроена на 4 пробела, звиняйте за длинные строки

lenaustkz84 07-12-2011 20:10 1811196

lxa85, Благодарю!
Как говориться, сколько людей, столько мнений. Сколько программистов - столько и кодов :)

Конечно, Ваша программа работает на все 100% :)
Понравилось то, что Ваш код мне показался более компактным, чем мой.
Ничего лишнего.
Век живи, век учись :)

По поводу моего окончательного кода, который получился в итоге.

По Вашему примеру убрала лишний цикл repeat...until();
который был предназначен для проверки ввода положительного числа.
Оставила прстую конструкцию if...else. Результат тот же, а лишнего ничего нет.
Как говориться, все гениальное просто :)

Все таки получилось оставить цикл repeat...until();
=> просто условие использования именно этого цикла было у меня в задании.

Получилось сделать красивенько i:=1;
=> мне просто так глаз радует, когда переменная i начинается именно с 1 :)

Получилось убрать двойное считывание переменной a,
т.е. раньше было дважды прописано readln(a); Теперь только один.
Просто это двойное считывание переменной a часто
выдавало не правильные результаты работы программы, что меня дико возмущало :o

Ну и просто убрала то, что и так очевидно. Т.е. сократила

Код:

if(a>max)then max:=a else max:=max;
if(a<min)then min:=a else min:=min;

на
Код:

if(a>max)then max:=a;
if(a<min)then min:=a;

И еще добавила одно условие во внутреннем цикле repeat...until();

Код:

if (i=1) then begin max := a; min := a; end;
В этой строчке я нашла решение многих проблем :)

Вот собственно мой код :)

Код:

{Программа для определения максимального  и минимального
значения из N введенных чисел}
program max_i_min_iz_N;
    uses crt;
    var N,min,max,a,i,m:integer;

    BEGIN
      clrscr;
        repeat
              write('Введите положительное число: '); readln(N); writeln();
              if (N<=0) then
              writeln('Число ',N,' не положительное.')

              else
                begin
                    write('Введите ',N,' число(-ла,-ел) через пробел: ');
                    i:=1;

                    repeat
                      read(a);
                      if (i=1) then begin max := a; min := a; end;
                      if(a>max)then max:=a;
                      if(a<min)then min:=a;
                      i:=i+1;
                    until(i>N);

            writeln();
            writeln('max=',max);
            writeln('min=',min);
 
            end; {end else}

        writeln(); writeln('Для продолжения программы нажмите цифру 1');
        writeln('Для завершения программы нажмите цифру 2'); writeln();
        readln(m); writeln();

        until(m=2);
    END.

CyberDaemon, Кажется теперь код точно не маньячный :lol:


Время: 07:59.

Время: 07:59.
© OSzone.net 2001-