Показать полную графическую версию : [решено] Pascal от новичка (ошибку не вижу)
lenaustkz84
02-12-2011, 13:13
Здравствуйте!
Я только начала изучать 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
Максимальное значение определяет безошибочно. »
А если ввести
-1 -2 -3 -4 -5? ;)
Ошибка тут:
max:=0; min:=0;
С чего бы вдруг максимуму и минимуму быть равным нулю?
lenaustkz84, ошибка в изначальном присвоении min:=0. у тебя выходит 0 всегда меньше положительного числа, т. е. условие a<min при положительном а никогда не выполнится.
и для решения этой задачи лучше использовать массивы
CyberDaemon
02-12-2011, 14:01
и для решения этой задачи лучше использовать массивы »
Почему?
lenaustkz84
02-12-2011, 14:01
Убрала из кода max:=0; min:=0 » все равно программа работает так же не верно.
А если ввести
-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
Все верно, простым убиранием обнуления преременных задачу не решить.
Думай, думай!
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
максимуму и минимуму сначала нужно присвоить значение первого введенного числа.
А потом уже сравнивать все последующие числа.
CyberDaemon, imho удобней
lenaustkz84
02-12-2011, 14:20
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
Hector, это если с введенными числами ещё что-то надо делать, то да. А если задача просто найти максиминимум - тогда самое простое - это обрабатывать введённое число сразу после ввода и больше его не хранить. А то вдруг с размерностью массива не угадаешь :)
lenaustkz84, маньячно :)
И как отработает прога, если в ответ на
"write('Введите любую цифру: '); readln(N); writeln();"
ввести "1"?
lenaustkz84
02-12-2011, 14:46
Ммм... ёлки-палки... только обрадовалась...
Если ввести 1, то... приходиться ввоить 3 значения, из которых программа без ошибки выбирает min и max.
То есть работает не с одним значением, как это нужно, а с тремя.
Это, наверное, потому что я задала i:=3;
Или нет. Наверное, потому что у меня изначально должно сравниваться 3 переменных, иначе программа не работает.
Кстати, для двойки такая же проблема.
Наверное, я сейчас добавлю отдельные операторы именно для значения 1 и 2.
Только, даже если будет работать, вообще муть какая-то получиться, наверное... :o
CyberDaemon
02-12-2011, 15:00
Именно.
Не надо вводить сначала два числа, а потом еще настойчиво ждать третьего.
Нужно просто после ввода первого из чисел - присвоить его и максимуму и минимуму, т.е. max=min=первое введенное число. Одна дополнительная строчка в первом варианте кода. При первом прогоне цикла инициализировать обе переменные введеным числом.
А еще можно поступить маньячно - какой там предел у типа integer? От -32768 до 32767?
Тогда в первом варианте вместо min:=0; max:=0; пишем max:=-32768; min:=32767 - тоже сработает - ибо любое введенное допустимое для integer число окачется внутри этих пределов :lol:
Наверное, я сейчас добавлю отдельные операторы именно для значения 1 и 2. »
Так и подмывает стереть мое сообщение, чтобы посмотреть, насколько монструозно можно решить задачку. Хотя, в плане обучения программированию - даже монстр полезен. Решено - не сотру, но спрячу :)
lenaustkz84
02-12-2011, 15:23
Вот новый код. Теперь, наверное, точно все работает.
И для двойки. И для единицы.
Вот как бы только написать его по-красивее? :)
А то уж больно он мне не кажется таким, как надо.
{Программа для определения максимального и минимального значения
из 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, 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, молодец, старайся, думай. :) Такие темы приятно читать и приятно помогать. :)
Все что вверху, уже не в счет!
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
CyberDaemon, загляну теперь в Ваше решение :)
lxa85, как раз в том отрывке кода уже все работает. Только i:=3; потому что это уже третяя переменная, которую начинает сравнивать программа. А предыдущие две - это были сравнения 1 и 2. Если ставить i:=1; то нужно дописывать еще по два значения. Например, нужно найти max и min из 7 значений. Тогда приходиться вводить не 7, а 9 значений. Чтобы убрать эту ошибку, я присвоила переменной i значение 3. Ну вот, что-то такое постаралась объяснить :)
CyberDaemon, по Вашему объяснению кажется все так просто :)
Как же я сама не догадалась?
Напишу программку заново :)
lxa85, сейчас пишу по новому :) Покажу, что получилось :)
lenaustkz84
03-12-2011, 10:20
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. Интересно то, что, если программу не закрыть, а продолжить дальше, то тогда программа начинает находить минимальное и максимальное число правильно. Но не из только что введенных значений, а из всех значений, которые были введены. Наверное, не понятно объясняю. Лучше картинку покажу :)
http://content.foto.mail.ru/mail/hello_lenka/12/i-19.jpg
Вариант 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
Вот еще по совету 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.
http://content.foto.mail.ru/mail/hello_lenka/12/i-20.jpg
Я уже достала Вас своими вопросами и кодами, наверное.
Но вообще стукаюсь глазами и не вижу, что делаю не так.
Не сочтите за труд, подскажите, где я ошибаюсь.
lenaustkz84, а почему ты от case отказалась? Он был вполне не дурен и к месту.
Пусть код будет чуть длиннее, ничего страшного. В условиях про универсальную формулу ничего не сказано. Докажи пользу от использования case и ты будешь молодец.
Дам тебе еще времени помучиться, а завтра напишу свой вариант решения. :)
P.S.
Защита от дурака: Ты уверена, что тебе введут положительную переменную N ? :modesty:
lenaustkz84
03-12-2011, 20:48
Вот и я думала тоже про отрицательное число 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, спасибо за совет :)
Посижу еще над программкой, подумаю :)
Как и обещал, привожу вариант решения в моей доработке.
Решение разумеется
{Программа для определения максимального
и минимального значения из 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
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:
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.