Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Сортировка строк. сложный случай


Страницы:   1 2

Pcrepair ©   (2012-07-27 08:10:00) 

Добрый день. Есть четыре компонента:
1. Строка, содержит текстовый файл(точнее текстовая часть ХТМЛ-страницы)
2. Строка, содержит несколько слов (слова поиска)
3. Рейтинг(число), результат работы функции function Index(const S1,S2:string; A:integer):integer;
4. Строка - URL из которого получена ХТМЛ-страница

По ходу работы программы получается пара "рейтинг - УРЛ", текстовый файл и слова поиска УЖЕ не важны
необходимо эти пары (сотни а то и тысячи строк) отсортировать по возрастанию(или убыванию), по значению Рейтинг(число), причем после сортировки Рейтинг тоже уже не нужен. в конечном варианте нужны только строки УРЛ, отсортированные по Рейтингу

Вопрос: какими способами можно все это сделать? первое что приходит на ум это TStringList, там есть пары, но сам пока еще пробовал. возможно кто то что то знает, уже?


Ega23   (2012-07-29 13:37:00) [1]


> TStringList - это массив строк со своими функциями сортировки.
>  А ему же нужен массив объектов из двух полей url и rating.
>  Можно тогда просто TList использовать и запихивать туда
> нужные объекты. Вобщем вариантов реализации много. Кто на
> что горазд.


А мужики-то не знают...


 TStringList = class;

 PStringItem = ^TStringItem;
 TStringItem = record
   FString: string;
   FObject: TObject;
 end;

 PStringItemList = ^TStringItemList;
 TStringItemList = array[0..MaxListSize] of TStringItem;
 TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;

 TStringList = class(TStrings)
 private
   FList: PStringItemList;


Не вижу никакого массива строк. Вижу массив рекордов TStringItem


Плохиш   (2012-07-29 12:55:00) [2]


> Михаил   (29.07.12 12:02) [22]
>
> > А TStringList - это, по-твоему, что?
>
>
> TStringList - это массив строк со своими функциями сортировки.

Мелкое у тебя представление о нëм. Даже справка над тобой смеëтся.


Михаил   (2012-07-29 12:03:00) [3]


> [21]


Т.е. вывел в StringGrid))) а не в StringList


Михаил   (2012-07-29 12:02:00) [4]


> А TStringList - это, по-твоему, что?


TStringList - это массив строк со своими функциями сортировки. А ему же нужен массив объектов из двух полей url и rating. Можно тогда просто TList использовать и запихивать туда нужные объекты. Вобщем вариантов реализации много. Кто на что горазд.


Михаил   (2012-07-29 11:59:00) [5]


> Спасибо, НО....
> визуальный компонент не подходит, хотя заманчиво, заманчиво
> до изучения record пока еще не дошел, пока немного знаком
> с TStringList его и использую


Что значит визуальный компонент? Я тебе реализовал в массиве из указателей. Просто для того чтобы был виден результат вывел в StringList. Можешь и не выводить


Pcrepair   (2012-07-29 11:57:00) [6]

Удалено модератором
Примечание: На ринг


Ega23   (2012-07-29 11:00:00) [7]


> Зачем тебе вообще этот TStringList. Запихни это все в одномерный
> массив из указателей на упакованную запись из двух полей
> String и Integer.


А TStringList - это, по-твоему, что?


Dimka Maslov   (2012-07-29 10:24:00) [8]

Типы данных, массивы, записи и сортировка структурированных данных является одной из основ обучения программированию. С этого надо начинать. Если до сих пор не начал - пора заканчивать, брать лопату и идти копать.


Inovet   (2012-07-29 10:15:00) [9]

> [16] Pcrepair ©   (29.07.12 09:42)
> до изучения record пока еще не дошел

Это основы, однако, а лезешь в более сложное.


Pcrepair   (2012-07-29 09:42:00) [10]

Спасибо, НО....
визуальный компонент не подходит, хотя заманчиво, заманчиво
до изучения record пока еще не дошел, пока немного знаком с TStringList его и использую


Михаил   (2012-07-28 21:47:00) [11]

Тут комменты на русском. А то там кракозябры вставились

unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Button1: TButton;
   StringGrid1: TStringGrid;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

// Наша запись с url и рейтингом
type
 PPara = ^TPara;
 TPara = packed record
   url : String;
   rate: Integer;
end;

var
 Form1: TForm1;
 List : array of PPara; // Массив для хранения указателей на записи

implementation

{$R *.dfm}

procedure qSort(l,r:longint);
var i,j:longint;
   q:Integer;
   zam: PPara;
begin
 i := l; j := r;
 q := List[(l+r) div 2].rate;
 repeat
   while (List[i].rate < q) do inc(i);
   while (q < List[j].rate) do dec(j);
   if (i <= j) then
   begin
     zam:=List[i];
     List[i]:=List[j];
     List[j]:=zam;
     inc(i);
     dec(j);
   end;
 until (i > j);
 if (l < j) then qSort(l,j);
 if (i < r) then qSort(i,r);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 p: PPara;
 i, n: Integer;
begin
// Запускаем ГСЧ
 Randomize;

// Создаем массив из 10000 записей с url и рейтингом
 SetLength(List, 10000);
 for i := 0 to High(List) do begin
   New(p);
   n := random(10000) + 1; // Генерируем рейтинг (от 1 до 10000)

   // Записываем реутинг и url
   p.url := 'url' + IntToStr(n);
   p.rate := n;
   List[i] := p;
 end;

// Сортируем методом QuickSort
 qSort(0, High(List));

// Выводим всю эту херь в StringGrid
// Выводится естественно дольше чем сортируется
 StringGrid1.ColCount := 2;
 StringGrid1.RowCount := 2;
 StringGrid1.FixedCols := 0;
 StringGrid1.Cells[0, 0] := 'URL';
 StringGrid1.Cells[1, 0] := 'Рейтинг';
 for i := 0 to High(List) do begin
   StringGrid1.Cells[0, i+1] := List[i].url;
   StringGrid1.Cells[1, i+1] := IntToStr(List[i].rate);
   StringGrid1.RowCount := StringGrid1.RowCount + 1;
 end;
 StringGrid1.RowCount := StringGrid1.RowCount - 1;
end;

end.


Михаил   (2012-07-28 21:45:00) [12]

Вот держи код модуля. Положишь на форму StringGrid и кнопку.
Было время, написал. Не ленись больше.


unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Button1: TButton;
   StringGrid1: TStringGrid;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

// Íàøà çàïèñü ñ url è ðåéòèíãîì
type
 PPara = ^TPara;
 TPara = packed record
   url : String;
   rate: Integer;
end;

var
 Form1: TForm1;
 List : array of PPara; // Ìàññèâ äëÿ õðàíåíèÿ óêàçàòåëåé íà çàïèñè

implementation

{$R *.dfm}

procedure qSort(l,r:longint);
var i,j:longint;
   q:Integer;
   zam: PPara;
begin
 i := l; j := r;
 q := List[(l+r) div 2].rate;
 repeat
   while (List[i].rate < q) do inc(i);
   while (q < List[j].rate) do dec(j);
   if (i j);
 if (l < j) then qSort(l,j);
 if (i < r) then qSort(i,r);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 p: PPara;
 i, n: Integer;
begin
// Çàïóñêàåì ÃÑ×
 Randomize;

// Ñîçäàåì ìàññèâ èç 10000 çàïèñåé ñ url è ðåéòèíãîì
 SetLength(List, 10000);
 for i := 0 to High(List) do begin
   New(p);
   n := random(10000) + 1; // Ãåíåðèðóåì ðåéòèíã (îò 1 äî 10000)

   // Çàïèñûâàåì ðåóòèíã è url
   p.url := 'url' + IntToStr(n);
   p.rate := n;
   List[i] := p;
 end;

// Ñîðòèðóåì ìåòîäîì QuickSort
 qSort(0, High(List));

// Âûâîäèì âñþ ýòó õåðü â StringGrid
// Âûâîäèòñÿ åñòåñòâåííî äîëüøå ÷åì ñîðòèðóåòñÿ
 StringGrid1.ColCount := 2;
 StringGrid1.RowCount := 2;
 StringGrid1.FixedCols := 0;
 StringGrid1.Cells[0, 0] := 'URL';
 StringGrid1.Cells[1, 0] := 'Ðåéòèíã';
 for i := 0 to High(List) do begin
   StringGrid1.Cells[0, i+1] := List[i].url;
   StringGrid1.Cells[1, i+1] := IntToStr(List[i].rate);
   StringGrid1.RowCount := StringGrid1.RowCount + 1;
 end;
 StringGrid1.RowCount := StringGrid1.RowCount - 1;
end;

end.


Михаил   (2012-07-28 21:24:00) [13]

Зачем тебе вообще этот TStringList. Запихни это все в одномерный массив из указателей на упакованную запись из двух полей String и Integer.


type
 PPara = ^TPara;
 TPara = packed record
   url : String;
   rate: Integer;
end;

var
 List : array of PPara;


После этого отсортируй все это алгоритмом QuickSort.
В интернете методов реализации QuickSort полно.
Вот например этот.
http://otadmina.ru/quicksort/

Модифицируй его под запись естественно.


Pcrepair   (2012-07-28 14:24:00) [14]

вот что получилось в результате, правда пришлось ввести ГлобПерем в качестве буфера. некоторые считают что так неправильно. сразу встречный вопрос - как правильно?


unit Unit1;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   Button1: TButton;
   Edit1: TEdit;
   Edit2: TEdit;
   Label1: TLabel;
   Label2: TLabel;
   Button2: TButton;
   Memo2: TMemo;
   procedure Button1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 Buffer:TStringList;  (*ГлобПерем для хранения строк-пар*)

implementation

{$R *.dfm}

(*=======================================================*)
(*  28 июля 2012г. сортировка пары текст=число*)

(* ПРОЦ накопление строк в буфере*)
procedure TForm1.Button1Click(Sender: TObject);
var
 T1: TStringList;
 Text:string;     Number:integer;
(*  встроенная в процедуру функция. сшивает две ПЕРЕМ в одну  *)
 function AddUrl(const A:string; const B:integer):TStringList;
 begin
   AddUrl:=TStringList.Create;
   AddUrl.AddObject(Text,Pointer(Number));
 end;
(*ввод пар в накопитель*)
begin
   T1:=TStringList.Create;
   Number:=StrToInt(Edit1.Text); (*ввод числа*)
   Text:=Edit2.Text;  (*ввод текста*)
   T1:=AddUrl(Text,Number); (*сборка двух ПЕРЕМ в одну*)
   Buffer.AddStrings(T1); (*накопление строк в ГлобПерем*)
   Memo1.Text:=Buffer.text; (*контроль*)
   T1.Free;
end;
(*=====================================================*)

(*=====================================================*)
(* ПРОЦ сортировка строк из ГлобПерем*)
procedure TForm1.Button2Click(Sender: TObject);
var
 T: TStringList;

 function Compare(List: TStringList; Index1, Index2: Integer): Integer;
 begin
   if Integer(List.Objects[Index1])>Integer(List.Objects[Index2]) then Result:=-1
   (* сейчас сортировка - максимум наверху, если 1 а далее -1 тогда наверху минимум*)
   else if Integer(List.Objects[Index1])<Integer(List.Objects[Index2]) then Result:=1
   else Result:=0;
 end;

begin
  T:=TStringList.Create;
  T.AddStrings(Buffer); (*ввод накопленных пар*)
  T.CustomSort(@Compare); (*сортировка от 1 до максимума*)
  Memo2.Lines.Assign(T); (*контроль*)
  T.Free;
end;
(*====================================================*)
(*инизиализация буфера при запуске программы*)
procedure TForm1.FormCreate(Sender: TObject);
begin
 Buffer:=TStringList.Create;
end;

end.


Pcrepair   (2012-07-27 17:05:00) [15]

чиста для прикола. небольшое интеллектуальное развлечение.
а чо?


Плохиш   (2012-07-27 16:20:00) [16]


> Pcrepair ©   (27.07.12 16:12) [7]

Зачем оно тебе, это программирование?


Медвежонок Пятачок   (2012-07-27 16:18:00) [17]

или ты хочешь сказать, что если бы в стринглисте были бы не строки, то ты был бы счастлив?


Медвежонок Пятачок   (2012-07-27 16:17:00) [18]

ничего конечно.


Pcrepair   (2012-07-27 16:12:00) [19]

а ничего что имя=число и значение=строка? вот тут неясно. или число в строку?


Плохиш   (2012-07-27 15:24:00) [20]


> Pcrepair ©   (27.07.12 14:41) [4]

TStringList прекрасно работает с парами "имя"="значение", даже имеет специальные свойства/методы.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо