Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Многомерные массивы


Автор: OuterHeaven 8.4.2008, 01:36
Я учусь на первом курсе в университете по специальности "Инженер по информационным системам и технологиям. Передо мной стоит задача, написать программу по этому условию: Дано 100 вещественных чисел. Вычислить разность между максимальным и минимальным из них.

Написал исходный текст: на делфи

Цитата

{Нажатие кнопки вычислить}
procedure TForm1.Button1Click(Sender: TObject);


var
   a:   array[1..100] of real;   
   i:   integer;                       
   max: real;                     
   min: real;                         
   rez: real;                            

{Вводим массив}
begin

     for i:= 1 to 100 do
     a[i]:= StrToFloat(StringGrid1.cells [i-1,0]);

     max:= a[1];
     min:= a[1];
      for i:= 1 to 100 do
       begin
            if a[i] > max
             then
              max:= a[i];
              if a[i] < max
               then
               min:= a[i];
       rez:= max - min;

       label1.Caption:='Минимальный элемент массива: ' + FloatToStr(min) + #13 +
       'Максимальный элемент массива: ' + FloatToStr(max) + #13 +
       'Разность между максмильным и минимальным значением: ' + FloatToStr(rez);

       end;
end;


Конечно же я воспользовался формой StringGrid. Задал параметры для 100 чисел (сделал таблицей 10х10), но возникает несколько проблем:

Программа запускается. Я вношу 100 чисел и при нажатии кнопки вычислить программа выдает ошибку Project Project1.exe raised exception class EConvertError with message"' is not a valid floating point value' Process stopped. Use Step or Run to continue.

Я вношу поправку в циклы for, меняю значения (вместо 100 ставлю 5). Программа работает, но при вводе чисел в таком порядке 3 5 1 4 выдает, что минимальный элемент массива 2 (хотя должен быть 1). При вводе по порядку выдает все правильно.

Помогите пожалуйста разобраться...
 smile 

Автор: WaReZMEN 8.4.2008, 04:00
Вопервых ты пишеш 4 элемента 
Цитата
3 5 1 4
 а в масив пытаешся в пихнуть 5 от сюда и ошибка она говорит чтоне может преоброзовать струку и реал...
 
Цитата

Project1.exe raised exception class EConvertError with message"' is not a valid floating point value' Process stopped. Use Step or Run to continue.

Возможно ты напутал с кол-вом строк и столбцов в stringrid.
P.S. можно в строчке 
Код

for i:= 1 to 100 do
     a[i]:= StrToFloat(StringGrid1.cells [i-1,0]);


сделать так
Код

     for i:= 1 to 4 do
     If  StringGrid1.cells [i,1]<>'' then
       a[i]:= StrToFloat(StringGrid1.cells [i,1]);

Но никто не гарантирует что никто туда не впишет букву smile но это тоже можно проверять....

Вот тебе пример все работает как надо..

Автор: OuterHeaven 8.4.2008, 16:25
Огромное СПС. Это я понял. Но кто мне объяснит это на примере двумерного или многомерного массива? Надо ведь массив для 100 чисел... Помогите пожалуйста, буду очень признателен.

Автор: OuterHeaven 8.4.2008, 17:08
Цитата

 for i:= 1 to 4 do
     If  StringGrid1.cells [i,1]<>'' then
       a[i]:= StrToFloat(StringGrid1.cells [i,1]);


И еще вопрос мне не понятно, что это за параметры StringGrid.cells? (выделено красным цветом)

Автор: WaReZMEN 9.4.2008, 00:15
OuterHeaven ,
Цитата
 [i,1] 
 это столбец и строчка для многомерного масива все тоже очень просто делается .... скажу тебе тока что забивать его из StringGrid ты замучаешся. у вырожение 
Код

If  StringGrid1.cells [i,1]<>'' then
       a[i]:= StrToFloat(StringGrid1.cells [i,1]);
 говорит о том что если текущий элемент стрингрида не пустои то преоброзовать его в Float. Но я повторюсь что  проверку пробелов, букв и прочих символо нужно также сделать...
И еще я себе струдом представляю (а проще говоря вообще не предстовляю) каим образом ты многомерный масив из StringGrid заполнять будеш ну двух мерный реально а трех???? 
Кстате поимоиму у тебя с алгоритмом что то не то ну тебе виднее....
Вот тебе пример 2-х мерного:

Автор: OuterHeaven 9.4.2008, 02:46
А как тогда мне поступить? Чем можно воспользоваться еще для ввода многомерного массива как не StringGrid. Мне нужен массив, который сосотоит из таблицы 10x10. В общей сложности я смогу ввести в него 100 чисел. И среди них должен найти наименьшее и наибольшее значение. К стати я пробовал твою программу она показывает неправильно минимальное число (если ввести числа не по порядку) Я только начинающий смотрю в чем проблема...

Автор: WaReZMEN 9.4.2008, 07:18
OuterHeaven, ну программа не моя а твоя smile  (к томуже я говорил что она не совсем правельно работает) в алгоритм вообще нивнекал и оно мне ненужно я всего лиш отвечал на вопрос.... по поводу  чем воспользоватся : оставь стрин грид просто сам почуствовал что каждый раз вводить 100 элементов малость утомляет поэтому нужно сделать сохранение в в файл или заполнение генератором случаиных чисел. 

Автор: OuterHeaven 9.4.2008, 15:33
Может если вам не трудно... Вы поможете мне. Просто я не знаю как исправить код, чтобы программа правильно находила минимальные числа, и как заполнить массив случайными числами? Какие функции используются для этого...

Заранее спасибо.

Автор: WaReZMEN 10.4.2008, 00:40
Ну все просто ошибка твоя в том что ищя минимальный элемент ты сравниваеш текущис максимальным и думаеш что если текущий меньше максимального то это минимальный это не так
Код

          if a[i,j] < max         then          min:= a[i,j];



а нужно так

Код

          if a[i,j] < min         then          min:= a[i,j];

 
Вторая ошибка в том что ты вычисляеш разницу между максимальным и минимальным элементом каждый раз и выводиш тоже каждый раз а это не правельно.
 Карочи вот тебе код учись студент  smile 

Автор: OuterHeaven 10.4.2008, 04:37
Надеюсь я тоже так когда нибудь смогу, ОГРОМНОЕ ВАМ СПАСИБО. Буду дальше учиться smile 

Автор: OuterHeaven 10.4.2008, 22:01
Код

procedure TForm1.Button1Click(Sender: TObject);
var

   a:   array[1..200,1..200] of Integer; //массив от 1 до 200 (это значит массив максимум может состоять из таблицы 200х200

   i:   integer; //Индекс колонок ???
   J:Integer;    //индекс строк ???
   max: real;    //Максимальное значение
   min: real;    //Минимальное значение
   rez: real;    //Результат

{Вводим массив}
begin

  For I:=1 To StringGrid1.ColCount-1 Do  //Это индекс колонок ??? (для чего они тут?)
    For J:=1 To StringGrid1.RowCount-1 Do  //Это индекс строк ??? (для чего они тут?)
       If  StringGrid1.cells [i,J]<>'' then  //Если текущий элемент StringGrid не пустой
          a[i,J]:= StrToInt(StringGrid1.cells [i,J]);  //то преобразовать его в Float

  max:=a[1,1];  //Мы предполагаем что максимальный элемент находится в поле [1,1]
  min:=a[1,1];  //Так же мы предполагаем что минимальный элемент находится в поле [1,1]
  For I:=1 To StringGrid1.ColCount-1 Do  //Начинаем цикл в первой колонке (так?)
    For J:=1 To StringGrid1.RowCount-1 Do  //Начинаем цикл в первой строке (так?)
       Begin
         IF a[i,J] > max  Then  max:= a[i,J];//Сравниваем текущий элемент с максимальным значением, если он больше максимального предыдущего то значение найдено
         IF a[i,j] < min  Then  min:= a[i,j];  //Сравниваем текущий элемент с минимальным значением, если он меньше минимального предыдущего то значение найдено
       end;

       rez:= max - min;
       label1.Caption:='Минимальный элемент массива: ' + FloatToStr(min) + #13 +
       'Максимальный элемент массива: ' + FloatToStr(max) + #13 +
       'Разность между максмильным и минимальным значением: ' + FloatToStr(rez);

end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  StringGrid1.RowCount:=StrToInt(Edit2.Text)+1; // ???
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
  StringGrid1.ColCount:=StrToInt(Edit1.Text)+1;  // ???
end;

procedure TForm1.Button2Click(Sender: TObject);  //По нажатии кнопки сгенерировать
var
  I,J:Integer;
begin
  Randomize;

  For I:=1 To StringGrid1.ColCount-1 Do         //Тут заполняем таблицу случайными числами с первой колонки и строки
    For J:=1 To StringGrid1.RowCount-1 Do
       StringGrid1.Cells[I,J]:=IntToStr(Random(1000));  //Генерируем числа от 0 - 1000

end;

end.


Вот у меня есть вопросы, правильно я прокоментировал исходный код? Там где мне не понятно, я выставил вопросы.
Заранее спс.

Автор: Kaboom 10.4.2008, 23:51
Все верно.

Маленькие замечания:

Код

For I:=1 To StringGrid1.ColCount-1 Do  //Это индекс колонок ??? (для чего они тут?)
    For J:=1 To StringGrid1.RowCount-1 Do  //Это индекс строк ??? (для чего они тут?)
        a[i,J]:= StrToInt(StringGrid1.cells [i,J]);

Этими циклами мы проходим весь StringGrid и загоняем значения ячеек в массив: сначала получаем ячейку [1,1],[1,2],...[1, StringGrid1.RowCount-1] - это первый ряд StringGrid'а, потом второй ..., третий и т. д.

Код

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  StringGrid1.RowCount:=StrToInt(Edit2.Text)+1; // ???
end;

При нажатии на кнопку SpeedButton1 количество строк в StringGrid'e станет равным числу введенному в Edit2 + 1

Код

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
  StringGrid1.ColCount:=StrToInt(Edit1.Text)+1;  // ???
end;

Аналогично для колонок.

Автор: WaReZMEN 11.4.2008, 00:24
OuterHeaven, Да правельно с учетами канечно с коректировкой Kaboom. 

Автор: OuterHeaven 12.4.2008, 00:11
Cпасибо БОЛЬШОЕ! smile  

Автор: Alex133 15.11.2009, 10:48
А можно попросить вас написать это на Паскале? ну пожалуйста..

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)