Имя пользователя:
Пароль:
 | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Разное - [решено] Pascal от новичка (ошибку не вижу)

Ответить
Настройки темы
Разное - [решено] Pascal от новичка (ошибку не вижу)

Аватара для lenaustkz84

Новый участник


Сообщения: 26
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изменения
Автор: lenaustkz84
Дата: 02-12-2011
Описание: исправление ошибки
Здравствуйте!

Я только начала изучать 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.

Отправлено: 13:13, 02-12-2011

 

Аватара для CyberDaemon

DOOMer


Сообщения: 3254
Благодарности: 438

Профиль | Отправить PM | Цитировать


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

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

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


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

-------
"640 K ought to be enough for anybody" Bill Gates, 1981


Последний раз редактировалось CyberDaemon, 02-12-2011 в 15:06.


Отправлено: 15:00, 02-12-2011 | #11



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Аватара для lenaustkz84

Новый участник


Сообщения: 26
Благодарности: 0

Профиль | Отправить PM | Цитировать


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

Код: Выделить весь код
{Программа для определения максимального  и минимального  значения
 из 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.

Последний раз редактировалось lenaustkz84, 02-12-2011 в 15:33.


Отправлено: 15:23, 02-12-2011 | #12


Аватара для lxa85

Необычный


Contributor


Сообщения: 4466
Благодарности: 995

Профиль | Сайт | Отправить PM | Цитировать


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);

-------
- Я не разрешаю тебе быть плохой! Потому что плохие люди совершают плохие поступки. А это нехорошо!
(Из наставлений 5 летней девочки своей младшей сестре)


Последний раз редактировалось lxa85, 02-12-2011 в 15:32.


Отправлено: 15:24, 02-12-2011 | #13


Аватара для lenaustkz84

Новый участник


Сообщения: 26
Благодарности: 0

Профиль | Отправить PM | Цитировать


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

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

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

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

Отправлено: 15:25, 02-12-2011 | #14


Аватара для lenaustkz84

Новый участник


Сообщения: 26
Благодарности: 0

Профиль | Отправить PM | Цитировать


CyberDaemon, lxa85, спасибо Вам за советы
Вот заново написала код.
Опять не слишком им довольна
Но думаю, уже лучше, чем было.
Не нравиться этот 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 в 10:29.


Отправлено: 10:20, 03-12-2011 | #15


Аватара для lenaustkz84

Новый участник


Сообщения: 26
Благодарности: 0

Профиль | Отправить PM | Цитировать


Вот еще по совету 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.


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

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

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

Отправлено: 14:59, 03-12-2011 | #16


Аватара для lxa85

Необычный


Contributor


Сообщения: 4466
Благодарности: 995

Профиль | Сайт | Отправить PM | Цитировать


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

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

-------
- Я не разрешаю тебе быть плохой! Потому что плохие люди совершают плохие поступки. А это нехорошо!
(Из наставлений 5 летней девочки своей младшей сестре)


Отправлено: 15:42, 03-12-2011 | #17


Аватара для lenaustkz84

Новый участник


Сообщения: 26
Благодарности: 0

Профиль | Отправить PM | Цитировать


Вот и я думала тоже про отрицательное число 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, спасибо за совет
Посижу еще над программкой, подумаю

Отправлено: 20:48, 03-12-2011 | #18


Аватара для lxa85

Необычный


Contributor


Сообщения: 4466
Благодарности: 995

Профиль | Сайт | Отправить PM | Цитировать


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

Код: Выделить весь код
{Программа для определения максимального
и минимального  значения из 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 пробела, звиняйте за длинные строки

-------
- Я не разрешаю тебе быть плохой! Потому что плохие люди совершают плохие поступки. А это нехорошо!
(Из наставлений 5 летней девочки своей младшей сестре)


Отправлено: 21:15, 04-12-2011 | #19


Аватара для lenaustkz84

Новый участник


Сообщения: 26
Благодарности: 0

Профиль | Отправить PM | Цитировать


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

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

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

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

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

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

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

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

Код: Выделить весь код
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, Кажется теперь код точно не маньячный

Отправлено: 20:10, 07-12-2011 | #20



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Разное - [решено] Pascal от новичка (ошибку не вижу)

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Разное - Всё о TURBO PASCAL (обсуждение, помощь в написание программ, ошибки, Pascal ABC) Loading Программирование и базы данных 41 20-05-2015 15:28
C/C++ - F1 для новичка SS3 Программирование и базы данных 5 24-01-2009 17:39
О проблемах новичка Direktor Finskogo Zaliva Программное обеспечение Linux и FreeBSD 2 29-03-2007 07:21
не вижу сервера, но вижу соседнии компьютеры DKolpakov Сетевые технологии 3 06-05-2005 14:43
Обучите новичка Micro Железо в Linux 45 15-04-2004 21:23




 
Переход