unit UFind;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Spin, ExtCtrls, Grids;

type
  TForm1 = class(TForm)
    GBVector: TGroupBox;
    SGA: TStringGrid;
    GBData: TGroupBox;
    BDim: TButton;
    RGType: TRadioGroup;
    CBSort: TCheckBox;
    GBRun: TGroupBox;
    Label3: TLabel;
    BRun: TButton;
    CBMethod: TComboBox;
    GroupBox5: TGroupBox;
    Label1: TLabel;
    Label6: TLabel;
    SEIndex: TSpinEdit;
    EX: TEdit;
    GBResult: TGroupBox;
    SGC: TStringGrid;
    GroupBox1: TGroupBox;
    Label2: TLabel;
    Label4: TLabel;
    SEDim1: TSpinEdit;
    SEDim2: TSpinEdit;
    procedure BDimClick(Sender: TObject);
    procedure BRunClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure SEDim2Change(Sender: TObject);
    procedure EXChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
uses Arrays, // Модуль методов сортировки и поиска
     Math;   // Для функции Min

{$R *.DFM}

var A: TArrayI2;
    B: TArrayR2;
    S: TArrayS2;
    RowI: TArrayI1;
    RowR: TArrayR1;
    RowS: TArrayS1;
    N, M: integer;
const MS = 2;
      MDep = 7;
      Dep: array[1..MDep] of string =
                ('Бухгалтерия',
                 'Управление',
                 'Цех 1',
                 'Цех 2',
                 'Цех 3',
                 'Цех 4',
                 'Цех 5');
      MFam = 10;
      Fam: array[1..MFam] of string =
                ('Иванов',
                 'Петров',
                 'Сидоров',
                 'Борисов',
                 'Антонов',
                 'Иванова',
                 'Петрова',
                 'Сидорова',
                 'Борисова',
                 'Антонова');

procedure TForm1.BDimClick(Sender: TObject);
var i, j: integer;
begin
 N := SEDim1.Value;
 if(RGType.ItemIndex = 2)
  then begin
   SEDim2.Value := MS;
   SEDim2.MaxValue := MS;
  end
  else SEDim2.MaxValue := 1000;
 SEIndex.MaxValue := SEDim2.MaxValue - 1;
 if(SEIndex.Value > SEIndex.MaxValue)
  then SEIndex.Value := SEIndex.MaxValue;
 M := SEDim2.Value;
 // Настройка размеров таблиц массивов
 SGA.Height := Min((N +1)* SGA.DefaultRowHeight + N, 270);
 SGA.RowCount := N;
 SGA.ColCount := M+1;
 SGC.ColCount := M+1;

// Задание размеров массива, заполнение массива
 case RGType.ItemIndex of
  0: begin
      SetLength(A,N,M);
      for i:= 0 to N-1 do
       for j:=0 to M-1 do
        A[i, j] := Random(100);
     end;
  1: begin
      SetLength(B,N,M);
      for i:= 0 to N-1 do
       for j:=0 to M-1 do
        B[i, j] := 1 + 99 * Random;
     end;
  2: begin
      SetLength(S,N,M);
      for i:= 0 to N-1 do begin
       S[i, 0] := Dep[1+Random(MDep)];
       S[i, 1] := Fam[1+Random(MFam)];
      end;
     end;
 end;
 // Заполнение таблиц
 for i:= 0 to N - 1 do begin
  // Заполнение первого столбца таблицы номерами строк
  SGA.Cells[0, i] := IntToStr(i+1);
  // Заполнение таблицы SGA случайными данными
  for j:=0 to M-1 do
   case RGType.ItemIndex of
    0: SGA.Cells[j+1, i] := IntToStr(A[i,j]);
    1: SGA.Cells[j+1, i] := FloatToStrF(B[i,j],ffGeneral,5,0);
    2: SGA.Cells[j+1, i] := S[i,j];
   end;
 end;

  // Заполнение первой строки таблицы результатов
  // номерами столбцов
 for i:= 1 to M do begin
   SGC.Cells[i,0] := IntToStr(i-1);
   SGC.Cells[i,1] := '';
 end;
 SGC.Cells[0,1] := '';
end;

procedure TForm1.BRunClick(Sender: TObject);
var i, j, XI:integer;
    XR: real;
    XS: string;
    L: boolean;

begin
// Перенос данных из таблицы в массив
 for i:= 0 to N - 1 do
  for j:=0 to M-1 do
   case RGType.ItemIndex of
    0: A[i,j] := StrToInt(SGA.Cells[j+1, i]);
    1: B[i,j] := StrToFloat(SGA.Cells[j+1, i]);
    2: S[i,j] := SGA.Cells[j+1, i];
   end;

// Сортировка массива
 if (CBSort.Checked) then begin
   case RGType.ItemIndex of
     0: MinSort2(A, SEIndex.Value);
     1: MinSort2(B, SEIndex.Value);
     2: MinSort2(S, SEIndex.Value);
   end;
// Перенос данных из массива в таблицу
   for i:= 0 to N - 1 do
    for j:=0 to M-1 do
     case RGType.ItemIndex of
      0: SGA.Cells[j+1, i] := IntToStr(A[i,j]);
      1: SGA.Cells[j+1, i] := FloatToStr(B[i,j]);
      2: SGA.Cells[j+1, i] := S[i,j];
     end;
 end;

// Чтение условий поиска
  try
   case RGType.ItemIndex of
    0: XI := StrToInt(EX.Text);
    1: XR := StrToFloat(EX.Text);
    2: XS := EX.Text;
   end;
  except
   Application.MessageBox('Неверный формат значения критерия',
                          'Исправьте неверное число',
                          MB_OK+MB_ICONSTOP);
   exit;
  end;

 // Поиск
 case CBMethod.ItemIndex of
  0: if (CBSort.Checked) then
      case RGType.ItemIndex of
       0: L := FindISort(A, XI, SEIndex.Value, RowI);
       1: L := FindRSort(B, XR, SEIndex.Value, RowR);
       2: L := FindSSort(S, XS, SEIndex.Value, RowS);
      end
     else
      case RGType.ItemIndex of
       0: L := FindI(A, XI, SEIndex.Value, RowI);
       1: L := FindR(B, XR, SEIndex.Value, RowR);
       2: L := FindS(S, XS, SEIndex.Value, RowS);
      end;
  1: if (CBSort.Checked) then
      case RGType.ItemIndex of
       0: FindNearISort(A, XI, SEIndex.Value, RowI);
       1: FindNearRSort(B, XR, SEIndex.Value, RowR);
       2: FindNearSSort(S, XS, SEIndex.Value, RowS);
      end
     else
      case RGType.ItemIndex of
       0: FindNearI(A, XI, SEIndex.Value, RowI);
       1: FindNearR(B, XR, SEIndex.Value, RowR);
       2: FindNearS(S, XS, SEIndex.Value, RowS);
      end;
  2: if(RGType.ItemIndex <> 1)
      then begin
       Application.MessageBox('Метод применим только для'+
                              #13'массивов действительных чисел',
                              'Ошибка',
                              MB_OK+MB_ICONSTOP);
       Exit;
      end
      else
       if(CBSort.Checked)
         then InterpRSort(B, XR, SEIndex.Value, RowR)
         else InterpR(B, XR, SEIndex.Value, RowR);
 end;
// Пересылка результатов поиска в таблицу
 if (CBMethod.ItemIndex = 0) and (not L)
 then begin
   Application.MessageBox('Искомая строка не найдена',
                          'Результат отрицательный',
                          MB_OK+MB_ICONEXCLAMATION);
   Exit;
 end;
 case RGType.ItemIndex of
  0: if(CBMethod.ItemIndex <> 2)
     then begin
      for i:=1 to M+1 do
       SGC.Cells[i,1] := IntToStr(RowI[i]);
      SGC.Cells[0,1] := IntToStr(RowI[0]+1);
     end
     else begin
      for i:=0 to M do
       SGC.Cells[i+1,1] := IntToStr(RowI[i]);
      SGC.Cells[0,1] := '';
     end;
  1: if(CBMethod.ItemIndex <> 2)
     then begin
      for i:=1 to M+1 do
       SGC.Cells[i,1] := FloatToStr(RowR[i]);
      SGC.Cells[0,1] := FloatToStr(RowR[0]+1);
     end
     else begin
      for i:=0 to M do
       SGC.Cells[i+1,1] := FloatToStr(RowR[i]);
      SGC.Cells[0,1] := '';
     end;
  2: if(CBMethod.ItemIndex <> 2)
     then begin
      for i:=1 to M do
       SGC.Cells[i,1] := RowS[i];
      SGC.Cells[0,1] := IntToStr(StrToInt(RowS[0])+1);
     end
     else begin
      for i:=0 to M do
       SGC.Cells[i+1,1] := RowS[i];
      SGC.Cells[0,1] := '';
     end;
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
// Обработчик события OnCreate формы
begin
// Вызов обработчика щелчка на кнопке BDim,
// чтобы установить размеры и значения массивов по умолчанию
 BDimClick(Sender);
// Задание метода по умолчанию: поиск точного совпадения
 CBMethod.ItemIndex := 0;
// Задание выдачи сообщений об ошибках
 ShowErrorArray := true;
end;

procedure TForm1.SEDim2Change(Sender: TObject);
begin
 // Настройка максимального значения индекса
 SEIndex.MaxValue := SEDim2.Value - 1;
 if(SEIndex.Value > SEIndex.MaxValue)
  then SEIndex.Value := SEIndex.MaxValue;
end;

procedure TForm1.EXChange(Sender: TObject);
// Ускоренный поиск
var i: integer;
begin
 if(RGType.ItemIndex <> 2) or (CBMethod.ItemIndex <> 1)
  then exit;
 FindNearS(S, EX.Text, SEIndex.Value, RowS);
 for i:=0 to M do
   SGC.Cells[i,1] := RowS[i];
end;

end.
