Сортировка линейного массива в лазарусе

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Сортировка линейного массива в лазарусе

Сообщение holysh » 11.12.2023 20:22:47

Сроки поджимают, а я туплю оч :roll:

Программа выглядит так:
в Edit1 пишу кол-во чисел, которые будут выведены в массив (ListBox1).
Нужно сделать так, чтобы при нажатии на кнопку, во второй листбокс выводилась такая сортировка массива:
первая половина сортируется по росту чисел, а вторая половина - по убыванию.

Буду очень благодарен за помощь
Вот часть моего кода (кнопка "Заполнить массив А):
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
  i, count: Integer;
begin
  // Получение количества чисел из Edit1
  count := StrToIntDef(Edit1.Text, 0);

  // Проверка на допустимость кол-ва чисел
  if (count > 0) and (count <= 100) then
  begin
    // Заполнение массива A ограничиньІм кол-вом чисел
    for i := 0 to count - 1 do
    begin
      if i mod 2 = 0 then
        A[i] := Random(101) // положительньІе числа для парньІх позиций
      else
        A[i] := -Random(101); // отрицательньІе числа для непарньІх позиций
    end;

    // ВьІводим ограниченньІй массив A в ListBox1
    ListBox1.Clear;
    for i := 0 to count - 1 do
      ListBox1.Items.Add(IntToStr(A[i]));
  end
  else
    ShowMessage('Введите значение количества (от 1 до 100).');
end;
holysh
незнакомец
 
Сообщения: 6
Зарегистрирован: 02.12.2023 16:06:08

Re: Сортировка линейного массива в лазарусе

Сообщение RRYTY » 11.12.2023 20:29:09

holysh писал(а):Нужно сделать так, чтобы при нажатии на кнопку, во второй листбокс выводилась такая сортировка массива:
первая половина сортируется по росту чисел, а вторая половина - по убыванию.


Все когда-то начинали. Удачи от души!

http://algolist.ru/
RRYTY
постоялец
 
Сообщения: 187
Зарегистрирован: 25.12.2021 10:00:32

Re: Сортировка линейного массива в лазарусе

Сообщение iskander » 11.12.2023 22:08:35

Если нет желания заморачиваться с сортировками, можно воспользоваться готовой реализацией:
Код: Выделить всё
...
uses
  ... Math, Generics.Collections, Generics.Defaults;
...
...
function IntCompDesc(constref L, R: Integer): Integer;
begin
  Result := CompareValue(R, L);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, count, half: Integer;
begin
  // Получение количества чисел из Edit1
  count := StrToIntDef(Edit1.Text, 0);

  // Проверка на допустимость кол-ва чисел
  if (count > 0) and (count <= 100) then
  begin
    // Заполнение массива A ограничиньІм кол-вом чисел
    for i := 0 to count - 1 do
    begin
      if i mod 2 = 0 then
        A[i] := Random(101) // положительньІе числа для парньІх позиций
      else
        A[i] := -Random(101); // отрицательньІе числа для непарньІх позиций
    end;

    // ВьІводим ограниченньІй массив A в ListBox1
    ListBox1.Clear;
    for i := 0 to count - 1 do
      ListBox1.Items.Add(IntToStr(A[i]));
    // сортировка
    half := count div 2;
    specialize TArrayHelper<Integer>.Sort(A[0..half-1]);
    specialize TArrayHelper<Integer>.Sort(A[half..count-1], specialize TComparer<Integer>.Construct(@IntCompDesc));
    //
    ListBox2.Clear;
    for i := 0 to count - 1 do
      ListBox2.Items.Add(A[i].ToString);     
  end
  else
    ShowMessage('Введите значение количества (от 1 до 100).');
end;
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Сортировка линейного массива в лазарусе

Сообщение holysh » 12.12.2023 00:07:09

iskander
Очень благодарен! :lol:
единственное, что хотелось бьІ пофиксить:
там всего 4 кнопки задействованьІ. Первая кнопка заполняет массив в листбокс1, вторая же сортирует по росту в листбоксе2, третяя - аналогично, только по убьІванию. А вот четвертая кнопка должна сортировать одну половину так, а вторую так. В данном случае все получается только если четвертую кнопку нажимать сразу после первой (заполнение массива). Если же ее нажать после 2 и 3, то результат вообще странньІй: первая половина положительньІе числа, вторая половина - нули.
Мне же нужно чтобьІ 4я кнопка работала как надо даже после 2 и 3.
Заранее еще раз спасибо, добавлю цельІй код:
Код: Выделить всё
var
  Form1: TForm1;
  A: array[1..100] of Integer;
implementation
{$R *.lfm}
{ TForm1 }

procedure TForm1.Button2Click(Sender: TObject);
var
  i, j, temp: Integer;
begin
   // Сортировка массива A по росту
  for i := 0 to 98 do
    for j := i + 1 to 99 do
      if (A[i] <> 0) and (A[j] <> 0) and (A[i] > A[j]) then
      begin
        temp := A[i];
        A[i] := A[j];
        A[j] := temp;
      end;

  // ВьІвод отсортированного массива A в ListBox2
  ListBox2.Clear;
  for i := 0 to 99 do
    if A[i] <> 0 then
      ListBox2.Items.Add(IntToStr(A[i]));
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i, j, temp: Integer;
begin
  // Сортировка массива А по убьІванию
  for i := 0 to 98 do
    for j := i + 1 to 99 do
      if A[i] < A[j] then
      begin
        temp := A[i];
        A[i] := A[j];
        A[j] := temp;
      end;

  // ВьІвод отсортированного массива А в ListBox2
  ListBox2.Clear;
  for i := 0 to 99 do
    if A[i] <> 0 then
    ListBox2.Items.Add(IntToStr(A[i]));
end;

function IntCompDesc(constref L, R: Integer): Integer;
begin
  Result := CompareValue(R, L);
end;
procedure TForm1.Button4Click(Sender: TObject);
var
  i, count, half: Integer;
begin
  count := StrToIntDef(Edit1.Text, 0);
  if (count > 0) and (count <= 100) then
  begin
  //sortirovka
    half := count div 2;
    specialize TArrayHelper<Integer>.Sort(A[0..half-1]);
    specialize TArrayHelper<Integer>.Sort(A[half..count-1], specialize TComparer<Integer>.Construct(@IntCompDesc));
    //
    ListBox2.Clear;
    for i := 0 to count - 1 do
      ListBox2.Items.Add(A[i].ToString);
  end;

  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, count, half: Integer;
begin
  // Получение кол-ва чисел с Edit1
  count := StrToIntDef(Edit1.Text, 0);

  // Проверка на допустимость кол-ва чисел
  if (count > 0) and (count <= 100) then
  begin
    // Заполнение массива A ограниченньІм кол-вом чисел
    for i := 0 to count - 1 do
    begin
      if i mod 2 = 0 then
        A[i] := Random(101) // положительньІе числа для парньІх позиций
      else
        A[i] := -Random(101); // отрицательньІе числа для непарньІх позиций
    end;

    // ВьІвод ограниченного массива A в ListBox1
    ListBox1.Clear;
    for i := 0 to count - 1 do
      ListBox1.Items.Add(IntToStr(A[i]));
  end
  else
    ShowMessage('Введите значение количества (от 1 до 100).');
end;

end.


Добавлено спустя 4 минуты 12 секунд:
RRYTY
благодарю :D
holysh
незнакомец
 
Сообщения: 6
Зарегистрирован: 02.12.2023 16:06:08

Re: Сортировка линейного массива в лазарусе

Сообщение iskander » 12.12.2023 12:09:17

holysh писал(а):добавлю цельІй код:

Если бы я сказал, что с этого следовало начинать, это была бы неправда, потому что начинать следовало бы с текста задания, к которому приложен текущий проект, чтобы помогальщикам, если таковые найдутся не нужно было рассовывать кнопочки по формочкам.
Что же мы видим: имеется статический массив А[1..100], который заполняется частично, начиная с нулевого индекса, но сортируется всегда целиком. Если в параметрах проекта включить проверку диапазона, это даже не скомпилируется.
Предлагаю заменить статический массив динамическим, ну и сортировки лучше вынести в отдельные процедуры, принимающие открытый массив, тогда не нужен будет Generics.Collections.
Код: Выделить всё
var
  Form1: TForm1;

  A: array of Integer;

  procedure Sort(var a: array of Integer);
  procedure SortDesc(var a: array of Integer);

implementation

{$R *.lfm}

{ TForm1 }

procedure Sort(var a: array of Integer);
var
  i, j, temp: Integer;
begin
  // Сортировка массива A по росту
for i := 0 to High(a)-1 do
   for j := i + 1 to High(a) do
     if a[i] > a[j] then
     begin
       temp := a[i];
       a[i] := a[j];
       a[j] := temp;
     end;
end;

procedure SortDesc(var a: array of Integer);
var
  i, j, temp: Integer;
begin
// Сортировка массива А по убьІванию
  for i := 0 to High(a)-1 do
    for j := i + 1 to High(a) do
      if a[i] < a[j] then
      begin
        temp := a[i];
        a[i] := a[j];
        a[j] := temp;
      end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i: Integer;
begin
  Sort(A);
  // ВьІвод отсортированного массива A в ListBox2
  ListBox2.Clear;
  for i := 0 to High(A) do
    ListBox2.Items.Add(IntToStr(A[i]));
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i: Integer;
begin
  SortDesc(A);
  // ВьІвод отсортированного массива А в ListBox2
  ListBox2.Clear;
  for i := 0 to High(A) do
    ListBox2.Items.Add(IntToStr(A[i]));
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  i, half: Integer;
begin
  if Length(A) > 1 then
  begin
    half := Length(A) div 2;
    Sort(A[0..half-1]);
    SortDesc(A[half..High(A)]);
    ListBox2.Clear;
    for i := 0 to High(A) do
      ListBox2.Items.Add(A[i].ToString);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, count: Integer;
begin
  // Получение кол-ва чисел с Edit1
  count := StrToIntDef(Edit1.Text, 0);

  // Проверка на допустимость кол-ва чисел
  if (count > 0) and (count <= 100) then
  begin
    SetLength(A, count);
    // Заполнение массива A ограниченньІм кол-вом чисел
    for i := 0 to High(A) do
    begin
      if i mod 2 = 0 then
        A[i] := Random(101) // положительньІе числа для парньІх позиций
      else
        A[i] := -Random(101); // отрицательньІе числа для непарньІх позиций
    end;

    // ВьІвод ограниченного массива A в ListBox1
    ListBox1.Clear;
    for i := 0 to High(A) do
      ListBox1.Items.Add(IntToStr(A[i]));
  end
  else
    ShowMessage('Введите значение количества (от 1 до 100).');
end;

end.

Как-то так, при условии, что я правильно понял задание.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Сортировка линейного массива в лазарусе

Сообщение holysh » 12.12.2023 17:32:43

iskander
сейчас сортирует в первой половине лишь положительньІе числа, а во второй - отрицательньІе.
Приведу пример того, как должно бьІть:
Массив:
2
-5
12
-9
15
-80
33
-60
56
-99
Сортировка:
-9
-5
2
12
15
56
33
-60
-80
-99
holysh
незнакомец
 
Сообщения: 6
Зарегистрирован: 02.12.2023 16:06:08

Re: Сортировка линейного массива в лазарусе

Сообщение iskander » 12.12.2023 17:59:11

Давайте-ка всю последовательность ваших действий и что при этом ожидается увидеть.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Сортировка линейного массива в лазарусе

Сообщение stikriz11 » 12.12.2023 18:12:09

Есть такой класс TList. У него есть метод Sort. Этот метод сортирует вот таким методом Procedure QuickSort(FList: PPointerList; L, R : Longint; Compare: Compare);
Думаю, Вы сможете немного переделать для своего массива. Lists.inc Это алгоритм быстрой сортировки
stikriz11
постоялец
 
Сообщения: 114
Зарегистрирован: 04.09.2023 15:54:19

Re: Сортировка линейного массива в лазарусе

Сообщение holysh » 13.12.2023 14:26:20

iskander
https://www.imagevenue.com/ME17AJH3
https://www.imagevenue.com/ME17AJHA
Вот само задание

Добавлено спустя 1 час 12 минут 14 секунд:
holysh писал(а):iskander
https://www.imagevenue.com/ME17AJH3
https://www.imagevenue.com/ME17AJHA
Вот само задание

И вот, еще раз цельІй код. Все работает как задумано, кроме 4й кнопки
Код: Выделить всё
var
  Form1: TForm1;
  A: array[1..100] of Integer;
implementation
{$R *.lfm}
{ TForm1 }

procedure TForm1.Button2Click(Sender: TObject);
var
  i, j, temp: Integer;
begin
   // Сортировка массива A по росту
  for i := 0 to 98 do
    for j := i + 1 to 99 do
      if (A[i] <> 0) and (A[j] <> 0) and (A[i] > A[j]) then
      begin
        temp := A[i];
        A[i] := A[j];
        A[j] := temp;
      end;

  // ВьІвод отсортированного массива A в ListBox2
  ListBox2.Clear;
  for i := 0 to 99 do
    if A[i] <> 0 then
      ListBox2.Items.Add(IntToStr(A[i]));
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i, j, temp: Integer;
begin
  // Сортировка массива А по убьІванию
  for i := 0 to 98 do
    for j := i + 1 to 99 do
      if A[i] < A[j] then
      begin
        temp := A[i];
        A[i] := A[j];
        A[j] := temp;
      end;

  // ВьІвод отсортированного массива А в ListBox2
  ListBox2.Clear;
  for i := 0 to 99 do
    if A[i] <> 0 then
    ListBox2.Items.Add(IntToStr(A[i]));
end;

function IntCompDesc(constref L, R: Integer): Integer;
begin
  Result := CompareValue(R, L);
end;
procedure TForm1.Button4Click(Sender: TObject);
var
  i, count, half: Integer;
begin
  count := StrToIntDef(Edit1.Text, 0);
  if (count > 0) and (count <= 100) then
  begin
  //sortirovka
    half := count div 2;
    specialize TArrayHelper<Integer>.Sort(A[0..half-1]);
    specialize TArrayHelper<Integer>.Sort(A[half..count-1], specialize TComparer<Integer>.Construct(@IntCompDesc));
    //
    ListBox2.Clear;
    for i := 0 to count - 1 do
      ListBox2.Items.Add(A[i].ToString);
  end;

  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, count, half: Integer;
begin
  // Получение кол-ва чисел с Edit1
  count := StrToIntDef(Edit1.Text, 0);

  // Проверка на допустимость кол-ва чисел
  if (count > 0) and (count <= 100) then
  begin
    // Заполнение массива A ограниченньІм кол-вом чисел
    for i := 0 to count - 1 do
    begin
      if i mod 2 = 0 then
        A[i] := Random(101) // положительньІе числа для парньІх позиций
      else
        A[i] := -Random(101); // отрицательньІе числа для непарньІх позиций
    end;

    // ВьІвод ограниченного массива A в ListBox1
    ListBox1.Clear;
    for i := 0 to count - 1 do
      ListBox1.Items.Add(IntToStr(A[i]));
  end
  else
    ShowMessage('Введите значение количества (от 1 до 100).');
end;

end.
holysh
незнакомец
 
Сообщения: 6
Зарегистрирован: 02.12.2023 16:06:08

Re: Сортировка линейного массива в лазарусе

Сообщение iskander » 13.12.2023 17:35:06

stikriz11 писал(а):Есть такой класс TList. У него есть метод Sort. Этот метод сортирует вот таким методом Procedure QuickSort(FList: PPointerList; L, R : Longint; Compare: Compare);
Думаю, Вы сможете немного переделать для своего массива. Lists.inc Это алгоритм быстрой сортировки

TArrayHelper.Sort() тоже, и оба они представляют собой далеко не лучшие образцы реализации алгоритма сортировки.
А для сотни элементов вполне сгодится даже такой дремучий алгоритм как у ТС.

holysh писал(а):Все работает как задумано, кроме 4й кнопки

То есть было "задумано" заполнять, начиная с нуля, массив, который начинается с единицы?
А весь код из поста №5 был попросту проигнорирован?

holysh писал(а):skander
https://www.imagevenue.com/ME17AJH3
https://www.imagevenue.com/ME17AJHA
Вот само задание

По ссылкам ничего не открывается, то ли cdn шалит, то ли роскомпозор.
Могу только предположить что вам требуется, чтобы исходный сгенерированный массив не изменялся в процессе сортировки(сортируем копии):

Код: Выделить всё
...
uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Edit1: TEdit;
    ListBox1: TListBox;
    ListBox2: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

  A: array of Integer;

  procedure Sort(var a: array of Integer);
  procedure SortDesc(var a: array of Integer);

implementation

{$R *.lfm}

{ TForm1 }

procedure Sort(var a: array of Integer);
var
  i, j, temp: Integer;
begin// по возрастанию
  for i := 0 to High(a)-1 do
    for j := i + 1 to High(a) do
      if a[i] > a[j] then begin
        temp := a[i];
        a[i] := a[j];
        a[j] := temp;
      end;
end;

procedure SortDesc(var a: array of Integer);
var
  i, j, temp: Integer;
begin// по убыванию
  for i := 0 to High(a)-1 do
    for j := i + 1 to High(a) do
      if a[i] < a[j] then begin
        temp := a[i];
        a[i] := a[j];
        a[j] := temp;
      end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i: Integer;
  ACopy: array of Integer;
begin
  ACopy := Copy(A);
  Sort(ACopy); // по возрастанию
  ListBox2.Clear;
  for i := 0 to High(ACopy) do
    ListBox2.Items.Add(ACopy[i].ToString);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i: Integer;
  ACopy: array of Integer;
begin
  ACopy := Copy(A);
  SortDesc(ACopy); // по убыванию
  ListBox2.Clear;
  for i := 0 to High(ACopy) do
    ListBox2.Items.Add(ACopy[i].ToString);
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  i, half: Integer;
  ACopy: array of Integer;
begin
  if Length(A) > 1 then begin
    ACopy := Copy(A);
    half := Length(ACopy) div 2;
    Sort(ACopy[0..half-1]);             // по возрастанию
    SortDesc(ACopy[half..High(ACopy)]); // по убыванию
    ListBox2.Clear;
    for i := 0 to High(ACopy) do
      ListBox2.Items.Add(ACopy[i].ToString);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, count: Integer;
begin// генерация массива
  count := StrToIntDef(Edit1.Text, 0);
  if (count > 0) and (count <= 100) then begin
    SetLength(A, count);
    for i := 0 to High(A) do
      if i mod 2 = 0 then
        A[i] := Random(101)
      else
        A[i] := -Random(101);
    ListBox1.Clear;
    for i := 0 to High(A) do
      ListBox1.Items.Add(A[i].ToString);
  end else
    ShowMessage('Введите значение количества (от 1 до 100).');
end;

end.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Сортировка линейного массива в лазарусе

Сообщение stikriz11 » 13.12.2023 18:27:06

iskander писал(а):оба они представляют собой далеко не лучшие образцы реализации алгоритма сортировки.

Это Вы сейчас про классический алгоритм быстрой сортировки сказали?
stikriz11
постоялец
 
Сообщения: 114
Зарегистрирован: 04.09.2023 15:54:19

Re: Сортировка линейного массива в лазарусе

Сообщение holysh » 13.12.2023 18:29:53

iskander писал(а):А весь код из поста №5 был попросту проигнорирован?

пробовал, говорю же, выходило так что первая половина сортирует исключительно положительные числа, а вторая отрицательные. А тот код что я последним скинул, то я по случайности вставил старый.
Только что попробовал последний предоженый Вами код, и все работает как надо :D
Благодарю от души, очень выручили! прошу прощения что забрал столько времени ибо сразу не додумался скинуть текст задания и целый код.. думал лишь в кнопке 4 чета там исправить и все будет работать но вышло немного сложнее. первый раз в лазарусе работаю
Еще раз спасибо
holysh
незнакомец
 
Сообщения: 6
Зарегистрирован: 02.12.2023 16:06:08

Re: Сортировка линейного массива в лазарусе

Сообщение iskander » 13.12.2023 19:36:55

Да не за что, приходите ещё.

stikriz11 писал(а):Это Вы сейчас про классический алгоритм быстрой сортировки сказали?

Слово "классический" предполагает какую-то каноническую форму, но вариантов реализации быстрой сортировки существует множество.
Первоначальный вариант сортировки Хоара в худшем случае имел временную сложность О(N^2) и пространственную О(N). Обе вышеупомянутые сортировки, а они одинаковы, одна скопирована с другой, по крайней мере в FPC-3.2.2, гарантируют пространственную сложность О(LogN), но временная сложность в худшем случае осталась квадратичной. В 21 веке это выглядит несколько архаично.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 22

Рейтинг@Mail.ru