Страница 1 из 1
Сортировка линейного массива в лазарусе
Добавлено: 11.12.2023 19:22:47
holysh
Сроки поджимают, а я туплю оч
Программа выглядит так:
в 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;
Re: Сортировка линейного массива в лазарусе
Добавлено: 11.12.2023 19:29:09
RRYTY
holysh писал(а):Нужно сделать так, чтобы при нажатии на кнопку, во второй листбокс выводилась такая сортировка массива:
первая половина сортируется по росту чисел, а вторая половина - по убыванию.
Все когда-то начинали. Удачи от души!
http://algolist.ru/
Re: Сортировка линейного массива в лазарусе
Добавлено: 11.12.2023 21:08:35
iskander
Если нет желания заморачиваться с сортировками, можно воспользоваться готовой реализацией:
Код: Выделить всё
...
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;
Re: Сортировка линейного массива в лазарусе
Добавлено: 11.12.2023 23:11:21
holysh
iskander
Очень благодарен!
единственное, что хотелось бьІ пофиксить:
там всего 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
благодарю

Re: Сортировка линейного массива в лазарусе
Добавлено: 12.12.2023 11:09:17
iskander
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.
Как-то так, при условии, что я правильно понял задание.
Re: Сортировка линейного массива в лазарусе
Добавлено: 12.12.2023 16:32:43
holysh
iskander
сейчас сортирует в первой половине лишь положительньІе числа, а во второй - отрицательньІе.
Приведу пример того, как должно бьІть:
Массив:
2
-5
12
-9
15
-80
33
-60
56
-99
Сортировка:
-9
-5
2
12
15
56
33
-60
-80
-99
Re: Сортировка линейного массива в лазарусе
Добавлено: 12.12.2023 16:59:11
iskander
Давайте-ка всю последовательность ваших действий и что при этом ожидается увидеть.
Re: Сортировка линейного массива в лазарусе
Добавлено: 12.12.2023 17:12:09
stikriz11
Есть такой класс TList. У него есть метод Sort. Этот метод сортирует вот таким методом Procedure QuickSort(FList: PPointerList; L, R : Longint; Compare: Compare);
Думаю, Вы сможете немного переделать для своего массива. Lists.inc Это алгоритм быстрой сортировки
Re: Сортировка линейного массива в лазарусе
Добавлено: 13.12.2023 14:38:34
holysh
iskander
https://www.imagevenue.com/ME17AJH3
https://www.imagevenue.com/ME17AJHA
Вот само задание
Добавлено спустя 1 час 12 минут 14 секунд:
И вот, еще раз цельІй код. Все работает как задумано, кроме 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.
Re: Сортировка линейного массива в лазарусе
Добавлено: 13.12.2023 16:35:06
iskander
stikriz11 писал(а):
Есть такой класс TList. У него есть метод Sort. Этот метод сортирует вот таким методом Procedure QuickSort(FList: PPointerList; L, R : Longint; Compare: Compare);
Думаю, Вы сможете немного переделать для своего массива. Lists.inc Это алгоритм быстрой сортировки
TArrayHelper.Sort() тоже, и оба они представляют собой далеко не лучшие образцы реализации алгоритма сортировки.
А для сотни элементов вполне сгодится даже такой дремучий алгоритм как у ТС.
holysh писал(а):Все работает как задумано, кроме 4й кнопки
То есть было "задумано" заполнять, начиная с нуля, массив, который начинается с единицы?
А весь код из поста №5 был попросту проигнорирован?
По ссылкам ничего не открывается, то ли 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.
Re: Сортировка линейного массива в лазарусе
Добавлено: 13.12.2023 17:27:06
stikriz11
iskander писал(а):оба они представляют собой далеко не лучшие образцы реализации алгоритма сортировки.
Это Вы сейчас про классический алгоритм быстрой сортировки сказали?
Re: Сортировка линейного массива в лазарусе
Добавлено: 13.12.2023 17:29:53
holysh
iskander писал(а):А весь код из поста №5 был попросту проигнорирован?
пробовал, говорю же, выходило так что первая половина сортирует исключительно положительные числа, а вторая отрицательные. А тот код что я последним скинул, то я по случайности вставил старый.
Только что попробовал последний предоженый Вами код, и все работает как надо 
Благодарю от души, очень выручили! прошу прощения что забрал столько времени ибо сразу не додумался скинуть текст задания и целый код.. думал лишь в кнопке 4 чета там исправить и все будет работать но вышло немного сложнее. первый раз в лазарусе работаю
Еще раз спасибо
Re: Сортировка линейного массива в лазарусе
Добавлено: 13.12.2023 18:36:55
iskander
Да не за что, приходите ещё.
stikriz11 писал(а):Это Вы сейчас про классический алгоритм быстрой сортировки сказали?
Слово "классический" предполагает какую-то каноническую форму, но вариантов реализации быстрой сортировки существует множество.
Первоначальный вариант сортировки Хоара в худшем случае имел временную сложность О(N^2) и пространственную О(N). Обе вышеупомянутые сортировки, а они одинаковы, одна скопирована с другой, по крайней мере в FPC-3.2.2, гарантируют пространственную сложность О(LogN), но временная сложность в худшем случае осталась квадратичной. В 21 веке это выглядит несколько архаично.