Помощь - Поиск - Пользователи - Календарь
Полная версия: Универсальная гистограмма.
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
3 kilos
Вобщем первоначальная задача была такова - ввести 7 чисел и получить по ним гистограмму. Программу я написал, вот её код

Код
program lab7;
uses crt, graph;
var j,k,err,x,y,y1,i,a:integer;
begin
i:=detect;
initgraph(i,j,'d:\bp\bgi');
err:=graphresult;
if err <> grOK then
writeln(grapherrormsg(Err))
else
  begin
  writeln('draiver:',getdrivername,'regim:',getModename(k));
  setcolor(15);
  x:=150;
  i:=0;
  y1:=400;
  outtext('vvedite 7 4isel A v %');
  outtextXY(110,455,'Diagramma vvedennyh zna4enii');
  rectangle(100,150,500,450);
   repeat
   y:=400;
   readln(a);
   setfillstyle(i+1,i+1);
   For
   k:=1 to a*2 do
    begin
    delay(500);
    y:=y-1;
    bar3d(x-30,y,x,y1,10,true);
    end;
   x:=x+50;
   i:=i+1;
   until i>7;
   closegraph;
   end;
   readln;
  end.


Но тут преподователь поставил мне новую задачу - пронормировать гистограмму. Зачем он это попросил? Отвечаю - программа не универсальна, т.е. если я введу например 1000, то соответствующий столбец гистограммы полезет куда-то вверх за экран. В чем заключается нормирование:

1 - Мы вводим 7 чисел, после которого находится максимальное число.
2 - Независимо какие остальные числа мы ввели, надо найти процентное соотношение этих чисел к самому максимальному числу. (т.е если максимальное число 300, то 30 - это 0.1 часть от 300)
3 - По этой процентной зависимости программа строит универсальную гистограмму. Т.Е. максимальному числу всегда будет соответствовать одна и та же высота столбца, а там уже как введем.


Вот тут и нужна мне ваша помощь, т.к. я так понял тут надо иметь дело с массивом( а с массивами я плохова-то дружу), но деревянным способом сравнивать 7 чисел - это кошмар. Еще я понял, программку наверное придется конкретно изменить smile.gif . Очень буду рад если поможете до вторника, иначе мне будет прямая угроза отчисления.
П.С. Процедуры естественно только приветствуются, иначе тут никак.
klem4
Храни 7 чисел в массиве, далее находи номер максимального элемента, далее сортируй массив по процентному отношения относительно наибольшего элемента и выводи гастаграмму, высота каждой точки кторой будет равна процентномуотношению относиельно максимального ...
3 kilos
Цитата(klem4 @ 4.03.2006 11:18) *

Храни 7 чисел в массиве, далее находи номер максимального элемента, далее сортируй массив по процентному отношения относительно наибольшего элемента и выводи гастаграмму, высота каждой точки кторой будет равна процентномуотношению относиельно максимального ...

Это я понимаю, что я прошу, так это код, ибо с массивами я плохо дружу smile.gif
klem4
У нас тут не принято решать задачу полностью ... что тебе не ясно в реализации ? Не умеешь работать с массивами ? У нас есть замечательный FAQ, в нем же найдешь и методы сортировок.
3 kilos
Цитата(klem4 @ 4.03.2006 11:23) *

У нас тут не принято решать задачу полностью ... что тебе не ясно в реализации ? Не умеешь работать с массивами ? У нас есть замечательный FAQ, в нем же найдешь и методы сортировок.


Я понимаю что не принято, но может найдется человек, который до вторника не поленится и напишет. Просто инфа отнимает очень много времени, а делов до вторника масса.
volvo
А может ты до вторника воспользуешься поиском и введешь в него слово "гистограмму"? Я, между прочим, выкладывал уже такое на форум...
3 kilos
Цитата(volvo @ 4.03.2006 12:10) *

А может ты до вторника воспользуешься поиском и введешь в него слово "гистограмма"? Я, между прочим, выкладывал уже такое на форум...


Поиск юзал первым делом, нашол 3 топика, но именно для моего случая не было проги.
volvo
ИМЕННО для твоего случая и не будет - для него надо заново открыть чистый лист и написать С НУЛЯ всю программу. А несколько строк (ввод массива) можешь и подправить до вторника ... Дай ссылки на 3 топика, которые ты нашел...
3 kilos
Цитата(volvo @ 4.03.2006 12:17) *

ИМЕННО для твоего случая и не будет - для него надо заново открыть чистый лист и написать С НУЛЯ всю программу. А несколько строк (ввод массива) можешь и подправить до вторника ... Дай ссылки на 3 топика, которые ты нашел...


Попробовал твою программу http://forum.pascal.net.ru/index.php?s=&sh...indpost&p=56448
Все бы хорошо, но при вводе чисел больше 100 гистограмма слетает. Да и та программа очень сложная по сравнению с моей.
volvo
Значит что-то не то изменял... Эта гистограмма ДОЛЖНА работать спокойно при значениях элемента массива до 5000 (это минимум, в принципе допустимо и до 30 тысяч)...

Вот тут тоже (ограничения - только касаюшиеся типа Integer):
Работа с каталогами и файлами

+ Здесь: Файлы и графика

... Еще примеры привести? Что, ВСЕ ЭТО не работает? А не кажется ли тебе, что это... Странновато? Все тестировали - все было в порядке, вдруг пришел ты, и перестало работать nea.gif

P.S. А насчет сложности - ты меня извини, но у тебя и масштабирования нет... Добавляешь функциональность - добавляется сложность, что ж ты хотел...
3 kilos
Написал 2 процедуры для нахождения процентного соотношения введенных чисел относительно максимального.

Код
PROGRAM M1;
USES crt;
TYPE
mas=array[1..7] of real;
VAR
a:mas;
max:real;
Procedure vvod_max(var a:mas; var max:real);
Var
i:byte;
num:byte;
Begin
max:=0;
for i:=1 to 7 do
  begin
  writeln('vvedite ',i,' element massiva !');
  readln(a[i]);
  if a[i]>max then
  max:=a[i]
  end
End;
Procedure proc(var a:mas; max:real);
Var
  i:byte;
Begin
  ClrScr;
  writeln('Protsentnoe sootnoshenie 4isel massiva :');
  for i:=1 to 7 do
   begin
   a[i]:=a[i]/max;
   writeln(i,' - ',a[i]:2:2)
   end;
  readln
End;
BEGIN
ClrScr;
vvod_max(a,max);
proc(a,max)
END.


Помогите хоть теперь состыковать полученные данные с высотой столбца диаграммы. Ну пожалуйста.
3 kilos
Вот что интересно, процентное соотношение - десятичное число. Гистограмма не может строиться по десятичным значениям, значит надо использовать округление ? Но при вводе очень больших и очень малых чисел одновременно округление может дать 0 - гистограммы вообще не будет кроме столбца с максимальным числом. Как тут быть?
volvo
uses crt;
type
  mas = array[1 .. 7] of real;

var
  a: mas;
  max: real;

procedure vvod_max(var a: mas; var max: real);
var
  i, num: byte;
begin
  max := 0;
  for i := 1 to 7 do begin
    write('vvedite ',i,' element massiva > '); readln(a[i]);
    if a[i] > max then max := a[i]
  end
end;

procedure proc(var a: mas; max: real; max_height: integer);
var i: byte;
begin
  clrscr;
  writeln('Protsentnoe sootnoshenie 4isel massiva :');
  for i := 1 to 7 do begin
    a[i] := (a[i] / max) * max_height;
    writeln(i,' - ',a[i]:2:2)
  end;
  readln
end;

procedure gist(a: mas);
var i, j: integer;
begin
  for i := 1 to 7 do begin
    for j := 1 to trunc(a[i]) + byte(frac(a[i]) > 0) do begin
      gotoxy(2*i, 25 - j); writeln(#177);
    end;
  end;
  readln
end;

BEGIN
  clrscr;
  vvod_max(a,max);
  proc(a, max, 23);
  gist(a);
END.

Так устроит?

Цитата
Но при вводе очень больших и очень малых чисел одновременно округление может дать 0 - гистограммы вообще не будет кроме столбца с максимальным числом
А ты попробуй в Excel ввести ОЧЕНЬ большие и ОЧЕНЬ маленькие числа, и по ним составить гистограмму...

Я смотрю, ты не совсем понимаешь смысл этого слова: "гистограмма"... Это СООТНОШЕНИЕ между элементами массива, следовательно если ты ввел
<1, 1, 1, 2, 3, 4, 5>, то все покажется нормально, а вот в случае
<1, 1, 1, 2, 30000, 4, 5> ОТНОШЕНИЕ максимального числа к остальным настолько велико, что остальными приходится пренебречь, и отображать только максимальное. Уж так получилось, что экран монитора имеет конечную разрешающую способность...
3 kilos
volvo

Преподаватель у нас просто с юмором. Сам еще просто наперед не мог представить, какие проблемы могут возникнуть. Я просто у него даже переспросил:

- А если я введу 1 и 1000000 то что будет?
- Ну 1 будет очень маленький кубик

Хех.

Пардон, но либо я не понял как твоя программа работает, либо чот не так считается. По какому принципу у тебя считается процентное соотношение?
Ввел следующие числа: 10 9 8 7 6 5 4
Получил данные:
1 - 23.00
2 - 20.70
3 - 18.40
4 - 16.10
5 - 13.80
6 - 11.50
7 - 9.20

Хотя по идее должно быть
1 - 1
2 - 0.9
3 - 0.8
4 - 0.7
5 - 0.6
6 - 0.5
7 - 0.4

Убрал умножение * max_height: процентное соотношение в порядке, но гистограмма вообще не та.
volvo
Цитата
По какому принципу у тебя считается процентное соотношение?
У меня там НЕ процентное соотношение считается, а сразу ВЫСОТА соответствующей колонки (чтоб 2 раза не считать)... Для этого и умножается на max_height.

Если же ты умножение убрал, то у тебя будут все колонки одинаковые - единичные. Ибо по определению процентное соотношение не может быть больше 1
3 kilos
Вот собсна товарисчи вам и окончательный вариант программы. Все как видите красиво, может кому пригодится. Тему можно закрывать, всем спасибо за участие, ждите еще вопросов =))

Код
PROGRAM M1;
USES crt,graph;
TYPE
    mas=array[1..7] of real;
VAR
a:mas;
max:real;
Procedure vvod_max(var a:mas; var max:real);
Var
  i:byte;
  num:byte;
Begin
  max:=0;
  for i:=1 to 7 do
   begin
    writeln('Vvedite ',i,' 4iclo');
    readln(a[i]);
    if a[i]>max then
    max:=a[i]
   end
End;
Procedure proc(var a:mas; max:real);
Var
i:byte;
Begin
ClrScr;
writeln('Vvedennie 4isla:');
for i:=1 to 7 do
  begin
   writeln(a[i]:2:0);
   end;
   writeln('Procentnoe sootnoshenie 4isel otnositelno maksimalnogo:');
   for i:=1 to 7 do
    begin
    a[i]:=(a[i]/max)*100;
    writeln(i,' - ',a[i]:5:2,'%')
   end;
  readln
End;
Procedure graf(a:mas);
var j,k,err,x,y,y1,i:integer;
Begin
  i:=detect;
  initgraph(i,j,'d:\bp\bgi');
  err:=graphresult;
  if err <> grOK then
  writeln(grapherrormsg(Err))
  else
   begin
   writeln('driver:',getdrivername,'regim:',getModename(k));
   setcolor(15);
   x:=150;
   i:=0;
   y1:=400;
   outtextXY(110,455,'Gistogramma vvedennih zna4enii');
   rectangle(100,150,500,450);
   repeat
    y:=400;
    setfillstyle(i+1,i+1);
    For k:=1 to trunc(a[i+1])*2 do
     begin
      delay(1000);
      y:=y-1;
      bar3d(x-30,y,x,y1,10,true);
     end;
    x:=x+50;
    i:=i+1;
   until i>6;
   readln;
   closegraph;
  end;
End;
BEGIN
ClrScr;
vvod_max(a,max);
proc(a,max);
graf(a)
END.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.