Консультация № 160902
19.02.2009, 15:16
0.00 руб.
0 9 1
У меня вопрос по решению задачи динамическими массивами.Не получается связать два шага?

Задание:
Шаг1. Создайте событие для кнопки «Ввод n». Для исследования скорости выполнения разных операций над массивами данных необходимо иметь возможность работать с данными из достаточно большого количества значений. Поэтому вам прелагается в этом методе случайным образом генерировать значение n и выводить его в текстовое окно. После определения размерности массива можно активизировать остальные кнопки.

procedure TForm1.BitBtn1 Click (Sender: TObject);
begin
Randomize;
Edit1.Clear;
For n := 1 To 10 Do
begin
A[n] := Random(10);
Edit1.Text := Edit1.Text +' ' + IntToStr(A[n]);
end;
end;

Шаг 2. Сгенерируйте массив целых чисел, сохраните его в памяти, и выполните вывод массива полученной размерности в окно Memo1:

procedure TForm1.Button1Click (Sender: TObject);
conct
type
TArray=array [1..n] of integer;
PArray=^TArray;
var
mas: PArray;
N, I: Integer;
begin
N := strtoint(edit1.text);
setlength(mas, n*mof(integer));
for I := 1 to N do mas[i] := random(N);
Memo1.Clear;
for I := 1 to N do memo1.Lines.Add(inttostr(mas[i]));
end;

Помогите пожалуйста в решение задачки!!!

Обсуждение

давно
Профессионал
153662
1070
20.02.2009, 13:07
общий
это ответ
Здравствуйте, Логинова Галина Петровна!
Вот исправил Ваши ошибки и всё заработало:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
n: integer;
A : array [1..10] of integer;
begin
Randomize;
Edit1.Clear;
For n := 1 To 10 Do
begin
A[n] := Random(10);
Edit1.Text := Edit1.Text +' ' + IntToStr(A[n]);
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
mas: Array of integer;
N, I: Integer;
begin
Randomize;
N := strtoint(edit1.text);
SetLength(mas, N);
for I := 0 to N - 1 do
mas[i] := random(N);
Memo1.Clear;
for I := 0 to N - 1 do
Memo1.Lines.Add(inttostr(mas[i]));
end;
Об авторе:
Мои программы со статусом freeware для Windows на моём сайте jonix.ucoz.ru

давно
Профессионал
153662
1070
20.02.2009, 13:15
общий
Если Вам надо генерировать в первом шаге произвольное число, то можно сделать следующим образом:
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
Randomize;
Edit1.Clear;
Edit1.Text := IntToStr(Random(1001));
end;

будет сгенерировано число от 0 до 1000, которое можно использовать для размерности массива во втором шаге или в первой процедуре убрать пробелы между цифрами заменив код
Код:
Edit1.Text := Edit1.Text + ' ' + IntToStr(A[n]);
на
Код:
Edit1.Text := Edit1.Text + IntToStr(A[n]);


Весь проект можно скачать URL >>отсюда
Об авторе:
Мои программы со статусом freeware для Windows на моём сайте jonix.ucoz.ru

Неизвестный
20.02.2009, 16:41
общий
Здравствуй Genia007 !
Спасибо, что откликнулся..Извини, я впервые на форуме.Может что-то не так написала.Но Задача такая:
Произвольную последовательность целых чисел надо рассортировать по убыванию значений.

Но выползает ошибка..
Вот,что у меня получилось!


unit UnitFirst;

interface

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

type
TFormFirst = class(TForm)
Panel1: TPanel;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
GroupBox1: TGroupBox;
Label4: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Label5: TLabel;
Label6: TLabel;
BitBtn1: TBitBtn;
Button1: TButton;
Button2: TButton;
Button3: TButton;
BitBtn2: TBitBtn;
Timer1: TTimer;
Memo1: TMemo;
ScrollBar1: TScrollBar;
ListBox1: TListBox;
ListBox2: TListBox;
procedure BitBtn2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);

procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);




private
{ Private declarations }
public
{ Public declarations }
end;
Type
mas = array [1..255] of integer;

var
FormFirst: TFormFirst;
a:mas;
n:integer;


implementation

{$R *.dfm}

procedure TFormFirst.BitBtn2Click(Sender: TObject);
begin
Close;
end;

procedure TFormFirst.FormCreate(Sender: TObject);
var
DateTime : TdateTime;
begin
Edit1.Clear;
Edit2.Clear;
Edit3.Clear;
Edit4.Clear;
Edit5.Clear;
Memo1.Lines.Clear;
DateTime:=Time;
Label4.Caption:=TimeToStr(DateTime);
end;

Создайте событие для кнопки «Ввод n». Для исследования скорости выполнения разных операций над массивами данных необходимо иметь возможность работать с данными из достаточно большого количества значений. Поэтому вам прелагается в этом методе случайным образом генерировать значение n и выводить его в текстовое окно. После определения размерности массива можно активизировать остальные кнопки

procedure TFormFirst.BitBtn1Click(Sender: TObject);
var
n: integer;
A : array [1..10] of integer;
begin
Randomize;
Edit1.Clear;
For n := 1 To 10 Do
begin
A[n] := Random(10);
Edit1.Text := Edit1.Text +' ' + IntToStr(A[n]);
end;
end;


Сгенерируйте массив целых чисел, сохраните его в памяти, и выполните вывод массива полученной размерности в окно Memo1:

procedure TFormFirst.Button1Click(Sender: TObject);
var
mas: Array of integer;
N, I: Integer;
begin
Randomize;
N := strtoint(edit1.text);
SetLength(mas, N);
for I := 0 to N - 1 do
mas[i] := random(N);
Memo1.Clear;
for I := 0 to N - 1 do
Memo1.Lines.Add(inttostr(mas[i]));
end;


Опишите следующее событие – запись полученного массива в окно ListBox1 со свойством упорядоченности. Вам предложено здесь вывести в окна Edit время начала операции записи чисел и время окончания записи всех чисел:
Создайте свой метод сортировки с помощью процедуры, которая не использует никаких компонент формы, не принадлежит методам формы, и работает только с ячейками памяти, в которых хранится сгенерированный вами массив.

procedure TFormFirst.Button2Click(Sender: TObject);
var d:Tdatetime;
begin
d:=now;
Edit2.Text:=Floattostr(d);
ListBox1.Items:= Memo1.Lines;
ListBox1.Sorted:=true;
Edit3.Text:= Floattostr(d);

end;


Создайте свой метод сортировки с помощью процедуры, которая не использует никаких компонент формы, не принадлежит методам формы, и работает только с ячейками памяти, в которых хранится сгенерированный вами массив.



Procedure sort(element: integer);
var
tmp:
begin
if element+1<Length(mas) then
case Sort_way of
0:begin // сортировка по возрастанию
if mas[element]>mas[element+1] then
begin
tmp:=mas[element];
mas[element]:=mas[element+1];
mas[element+1]:=tmp;
sort(element+1);
end;
end;
1:begin
if mas[element]<mas[element+1] then
begin
tmp:=mas[element];
mas[element]:=mas[element+1];
mas[element+1]:=tmp;
sort(element+1);
end;
end;
end;
end;


procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
begin
for i:=0 to length(mas)-1 do
sort(i);
end;




Создайте метод, обеспечивающий вызов процедуры сортировки, измерение времени сортировки в памяти, и вывода отсортированного массива в другой компонент ListBox:

procedure TFormFirst.Button3Click(Sender: TObject);
var
i,j:integer;
a:string;
d:Tdatetime;
begin
d:=now;
Edit4.Text:=Floattostr(d);
listbox2.Items.Clear;
listbox2.Items.AddStrings(listbox1.Items);
for i:=0 to listbox2.Count-1 do
for j:=i+1 to listbox2.Count-1 do
begin
if j=0 then
begin
if strtoint(listbox2.Items[i])>strtoint(listbox2.Items[j]) then
begin
a:=listbox2.Items[i];
listbox2.Items[i]:=listbox2.Items[j];
listbox2.Items[j]:=a;
end;
end
else
begin
if strtoint(listbox2.Items[i])<strtoint(listbox2.Items[j]) then
begin
Label6.Caption:='Время сортировки ' +#13+'массива в памяти ';
a:=listbox2.Items[i];
listbox2.Items[i]:=listbox2.Items[j];
listbox2.Items[j]:=a;
Edit5.Text:= Floattostr(d);
end;
end;
end;
end;
end.



Вот такая задачка...
С уважением galinko.
давно
Профессионал
153662
1070
20.02.2009, 19:17
общий
Вот поправил Ваш код, добавил своё, сравните скорость сортировки моей процедуры сортировки методом обмена и Ваш метод обратной сортировки на скорость обработки данных. Проект URL >>здесь. Надеюсь помог, если что, то завтра откликнусь.
Об авторе:
Мои программы со статусом freeware для Windows на моём сайте jonix.ucoz.ru

давно
Профессионал
153662
1070
20.02.2009, 20:45
общий
Я тут поигрался с Вашей процедурой сортировки в listbox2, ну очень долго, особенно если количество чисел в массиве за 1000, лучше сделайте так
Код:
Procedure sort(size: integer; vid: byte);
var
k: integer; // текущий элемент массива
changed: boolean; // TRUE, если в текущем цикле были обмены
buf: integer; // буфер для обмена элементами массива
begin
// сортировка массива методом обмена
repeat
Changed:= FALSE; // пусть в текущем цикле нет обменов
if vid = 0 then // сортируем по возрастанию
begin
for k:= 0 to size - 1 do
if mas[k] > mas[k + 1] then
begin // обменяем k-й и k+1-й элементы
buf := mas[k];
mas[k] := mas[k + 1];
mas[k + 1] := buf;
changed := TRUE;
end;
end
else // сортируем по убыванию
begin
for k:= 0 to size - 2 do
if mas[k] < mas[k + 1] then
begin // обменяем k-й и k+1-й элементы
buf := mas[k];
mas[k] := mas[k + 1];
mas[k + 1] := buf;
changed := TRUE;
end;
end;
until not changed; // если не было обменов, значит
// массив отсортирован
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
begin
listbox1.Clear;
Edit2.Text:= timetostr(time);
sort(length(mas), 0);
// вывод массива
for i:= 0 to length(mas) - 1 do
Form1.ListBox1.Items.Add(inttostr(mas[i]));
Edit3.Text:= timetostr(time);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
i: integer;
begin
Edit2.Text:= timetostr(time);
listbox2.Clear;
sort(length(mas), 1);
// вывод массива
for i:= 0 to length(mas) - 1 do
Form1.ListBox2.Items.Add(inttostr(mas[i]));
Edit3.Text:= timetostr(time);
end;
Об авторе:
Мои программы со статусом freeware для Windows на моём сайте jonix.ucoz.ru

давно
Профессионал
153662
1070
24.02.2009, 12:05
общий
Здравствуйте.
Странно, я выложил по ссылке готовую программу и её проект. Ваш код похожий на мой, и раз он работает значит ошибок нет. Можно дать несколько замечаний по улучшению, у Вас в процедурах по сортировки в циклах данные берутся из компонентов с формы listbox, что значительно замедляет работу процедуры, это хорошо видно на больших размерах массивов. Я думаю что лучше нужно взять временный массив, тот же mas и сортировать его. Проверте на количестве элементов порядка 1000, смотрите топик от 20.02.2009, 23:45. Для более детального комментария нужен весь текст из модуля .pas, есть непонятные моменты в Вашем коде, это либо опечатка либо недоработка.
Об авторе:
Мои программы со статусом freeware для Windows на моём сайте jonix.ucoz.ru

Неизвестный
25.02.2009, 23:01
общий
Genia007,Здравстуйте !
Я немного поправила свой код, правда он вышел корявый, но он работает.



unit Unit1;

interface

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

type
TForm1 = class(TForm)
Panel1: TPanel;
Memo1: TMemo;
ListBox1: TListBox;
ListBox2: TListBox;
ScrollBar1: TScrollBar;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
GroupBox1: TGroupBox;
Label4: TLabel;
BitBtn1: TBitBtn;
Button1: TButton;
Button2: TButton;
Button3: TButton;
BitBtn2: TBitBtn;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Label5: TLabel;
Label6: TLabel;
procedure BitBtn2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);



{ Private declarations }
public
{ Public declarations }
end;

Type
mas=array[1..600] of integer;
var
Form1: TForm1;
a:mas;
i,n:integer;

implementation

{$R *.dfm}

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
DateTime : TdateTime;
begin
Edit1.Clear;
Edit2.Clear;
Edit3.Clear;
Edit4.Clear;
Edit5.Clear;
Memo1.Lines.Clear;
DateTime:=Time;
Label4.Caption:=TimeToStr(DateTime);
end;



procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Randomize;
Edit1.Clear;
begin
A[N] := Random(10);
Edit1.Text := Edit1.Text +' ' + IntToStr(A[N]);
end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
mas: Array of integer;
N, I: Integer;
begin
Randomize;
N := strtoint(edit1.text);
SetLength(mas, N);
for I := 0 to N - 1 do
mas[i] := random(N);
Memo1.Clear;
for I := 0 to N do
Memo1.Lines.Add(inttostr(A[I]));
end;





procedure TForm1.Button2Click(Sender: TObject);
var
i, temp_1, temp_2: integer;
search: boolean;
temp: string;

begin
ListBox1.Clear; ListBox1.Sorted:= False; {очистка списка}
Edit2.Text:= TimeToStr(Now); {начальное время}
for i:= 0 to Memo1.Lines.Count - 1 do ListBox1.Items.Add(Memo1.Lines.Strings[i]); {перенос данных}

{процедура сортировки ListBox1 по возрастанию}
search:= True;
while search do
begin
search:= False;
for i:= 0 to ListBox1.Items.Count - 2 do
begin
temp_1:= StrToInt(ListBox1.Items.Strings[i]);
temp_2:= StrToInt(ListBox1.Items.Strings[i+1]);
if temp_1 < temp_2 then
begin
temp:= ListBox1.Items.Strings[i];
ListBox1.Items.Strings[i]:= ListBox1.Items.Strings[i+1];
ListBox1.Items.Strings[i+1]:= temp;
search:= True;
end;
end;
end;
{окончание процедуры сортировки}

Edit4.Text:= TimeToStr(Now); {конечное время}
end;

procedure TForm1.Button3Click(Sender: TObject);

var
i, j: integer;
a: string;
begin
Edit3.Text:= timetostr(time);
listbox2.Items.Clear;
listbox2.Items.AddStrings(listbox1.Items);
for i:= 0 to listbox2.Count-1 do
for j:= i + 1 to listbox2.Count-1 do
begin
if j= 0 then
begin
if strtoint(listbox2.Items[i]) > strtoint(listbox2.Items[j]) then
begin
a:= listbox2.Items[i];
listbox2.Items[i]:= listbox2.Items[j];
listbox2.Items[j]:= a;
end;
end
else
begin
if strtoint(listbox2.Items[i]) > strtoint(listbox2.Items[j]) then
begin
a:=listbox2.Items[i];
listbox2.Items[i]:= listbox2.Items[j];
listbox2.Items[j]:= a;
Edit5.Text:= timetostr(time);
Label6.Caption:='Время сортировки'+#13+'массива в памяти';
end;
end;
end;
end;



end.


Интересно, что тут у меня не так?
Спасибо, хорошо объяснил.
С уважением, galinko.
давно
Профессионал
153662
1070
27.02.2009, 12:20
общий
Здравствуйте.
Исходя из Вашего исходника можно найти ненужные переменный:
В объявлении глобальных переменных ненужные
i:integer; так как вообще не используются в программе.

Можно упростить следующие процедуры либо исправить:

procedure TForm1.FormCreate(Sender: TObject);
var
DateTime : TdateTime;
begin
Edit1.Clear;
Edit2.Clear;
Edit3.Clear;
Edit4.Clear;
Edit5.Clear;
Memo1.Lines.Clear;
DateTime:=Time;
Label4.Caption:=TimeToStr(DateTime);
end;
здесь можно не использовать не использовать переменную DateTime : TdateTime;
измените строчку Label4.Caption:=TimeToStr(DateTime);
на Label4.Caption:=TimeToStr(Time);
и убрать строчку DateTime:=Time;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Randomize;
Edit1.Clear;
begin
A[N] := Random(10);
Edit1.Text := Edit1.Text +' ' + IntToStr(A[N]);
end;
end;
здесь Вы пытаетесь получить массив А[n], но это не правильно нужно делать это при помощи цикла вот так
For n:= 1 to 600 do // до 600 потомучто Вы объявили массив А состоящий из 600 элементов
begin
A[n]:= Random(10);
Edit1.Text := Edit1.Text +' ' + IntToStr(A[N]);
end;
но тогда Вы не сможете этот результат из Edit1 использовать дальше, так как каждая цифра будет в поле через пробел и выскачет ошибка об не соответствии типов, а если убрать пробелы то ошибка что число выходит за рамки границ integer.

procedure TForm1.Button1Click(Sender: TObject);
var
mas: Array of integer;
N, I: Integer;
begin
Randomize;
N := strtoint(edit1.text);
SetLength(mas, N);
for I := 0 to N - 1 do
mas[i] := random(N);
Memo1.Clear;
for I := 0 to N do
Memo1.Lines.Add(inttostr(A[I]));
end;
здесь Вы получаете массив mas, а в Memo1 пытаетесь вывести массив А,
нужно переделать строку Memo1.Lines.Add(inttostr(A[I])); в строку
Memo1.Lines.Add(inttostr(mas[I])); соответственно и строку
for I := 0 to N - 1 do.

А про процедуры сортировки я уже писал.
Вот исправленный код посмотрите на скорости сортировки Ваших процедур, я их не трогал:
Код:
unit Unit1;

interface

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

type
TForm1 = class(TForm)
Panel1: TPanel;
Memo1: TMemo;
ListBox1: TListBox;
ListBox2: TListBox;
ScrollBar1: TScrollBar;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
GroupBox1: TGroupBox;
Label4: TLabel;
BitBtn1: TBitBtn;
Button1: TButton;
Button2: TButton;
Button3: TButton;
BitBtn2: TBitBtn;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Label5: TLabel;
Label6: TLabel;
procedure BitBtn2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);



{ Private declarations }
public
{ Public declarations }
end;

Type
mas=array[1..3] of integer;
var
Form1: TForm1;
a:mas;
n:integer;

implementation

{$R *.dfm}

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Clear;
Edit2.Clear;
Edit3.Clear;
Edit4.Clear;
Edit5.Clear;
Memo1.Lines.Clear;
Label4.Caption:=TimeToStr(Time);
end;



procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Randomize;
Edit1.Clear;
begin
for n:= 1 to 3 do
begin
A[N] := Random(10);
Edit1.Text := Edit1.Text + IntToStr(A[N]);
end;
end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
mas: Array of integer;
N, I: Integer;
begin
Randomize;
N := strtoint(edit1.text);
SetLength(mas, N);
for I := 0 to N - 1 do
mas[i] := random(N);
Memo1.Clear;
for I := 0 to N - 1 do
Memo1.Lines.Add(inttostr(mas[I]));
end;





procedure TForm1.Button2Click(Sender: TObject);
var
i, temp_1, temp_2: integer;
search: boolean;
temp: string;

begin
ListBox1.Clear; ListBox1.Sorted:= False; {î÷èñòêà ñïèñêà}
Edit2.Text:= TimeToStr(Now); {íà÷àëüíîå âðåìÿ}
for i:= 0 to Memo1.Lines.Count - 1 do ListBox1.Items.Add(Memo1.Lines.Strings[i]); {ïåðåíîñ äàííûõ}

{ïðîöåäóðà ñîðòèðîâêè ListBox1 ïî âîçðàñòàíèþ}
search:= True;
while search do
begin
search:= False;
for i:= 0 to ListBox1.Items.Count - 2 do
begin
temp_1:= StrToInt(ListBox1.Items.Strings[i]);
temp_2:= StrToInt(ListBox1.Items.Strings[i+1]);
if temp_1 < temp_2 then
begin
temp:= ListBox1.Items.Strings[i];
ListBox1.Items.Strings[i]:= ListBox1.Items.Strings[i+1];
ListBox1.Items.Strings[i+1]:= temp;
search:= True;
end;
end;
end;
{îêîí÷àíèå ïðîöåäóðû ñîðòèðîâêè}

Edit4.Text:= TimeToStr(Now); {êîíå÷íîå âðåìÿ}
end;

procedure TForm1.Button3Click(Sender: TObject);

var
i, j: integer;
a: string;
begin
Edit3.Text:= timetostr(time);
listbox2.Items.Clear;
listbox2.Items.AddStrings(listbox1.Items);
for i:= 0 to listbox2.Count-1 do
for j:= i + 1 to listbox2.Count-1 do
begin
if j= 0 then
begin
if strtoint(listbox2.Items[i]) > strtoint(listbox2.Items[j]) then
begin
a:= listbox2.Items[i];
listbox2.Items[i]:= listbox2.Items[j];
listbox2.Items[j]:= a;
end;
end
else
begin
if strtoint(listbox2.Items[i]) > strtoint(listbox2.Items[j]) then
begin
a:=listbox2.Items[i];
listbox2.Items[i]:= listbox2.Items[j];
listbox2.Items[j]:= a;
Edit5.Text:= timetostr(time);
Label6.Caption:='Âðåìÿ ñîðòèðîâêè'+#13+'ìàññèâà â ïàìÿòè';
end;
end;
end;
end;



end.
Об авторе:
Мои программы со статусом freeware для Windows на моём сайте jonix.ucoz.ru

Неизвестный
06.03.2009, 10:45
общий
Genia007!
Здравствуй!
[i]Спасибо большое, объяснил хорошо!
Я не больно то сильна в программирование, но стараюсь.
Интересно, как всё это получается....,когда состовляешь прграммы, и отчаиваешься, когда не получается.
Благодарю за помощь !!!! [/i]
Форма ответа