Author Topic: Delphi, работа с двусвязными списками  (Read 5829 times)

0 Members and 1 Guest are viewing this topic.

Offline Konstantine

  • Full Member
  • ***
  • Posts: 184
  • Karma: +1/-7
Здравствуйте Ребята.
Пишу курсовую по предмету Структуры обработки Алгоритмов данных

Решил использовать двусвязные списки и разобраться как работают с указателиями в delphi.
Вот программа(не работаеющая) ругается при выводе списка на экран.
Code: [Select]
type
  Plog = ^log;
    log = Record
      Wday:       String[3];
      Month:      String;
      MonthN:     Integer;
      Time:       String[8];
      Yea:        String[4];
      Duration:   integer;
      IP:         String;
      CODE:       String;
      Bytes:      integer;
      Metod:      String;
      URL:        String;
      Client:     String;
      IerarcheCode: String;
      TypeInfo:   String;
      Next,Prev:  Plog;
  end;
  ST = array[1..14] of String;

type
  TForm1 = class(TForm)
    Vivod: TButton;
    StringGrid1: TStringGrid;
    Zamena: TButton;
    Delete: TButton;
    Sort: TButton;
    procedure VivodClick(Sender: TObject);
    procedure CreateList(List: Plog);
    procedure AddToList(List: Plog; A: ST);
    procedure ViewList(List: Plog; i: integer);
    procedure DelToList(List, Kyrsor: Plog);
//Дважды связный список Лог (ОСиАЛД стр. 48)

var
  Tlog,head,foot: Plog;
  Form1: TForm1;

implementation

{$R *.xfm}



procedure TForm1.AddToList(List: Plog; A: ST);
var P: Plog;
begin
  if List<>nil then
    begin
    New(P);
    P.Wday:=A[1];
    P.Month:=A[2];
    P.MonthN:=StrToInt(A[3]);
    P.Time:=A[4];
    P.Yea:=A[5];
    P.Duration:=StrToInt(A[6]);
    P.IP:=A[7];
    P.CODE:=A[8];
    P.Bytes:=StrToInt(A[9]);
    P.Metod:=A[10];
    P.URL:=A[11];
    P.Client:=A[12];
    P.IerarcheCode:=A[13];
    P.TypeInfo:=A[14];
    P^.Next:=Nil;
    P^.Prev:=List.Next;
    List^.Next:=P.Prev;
    //Сдвигаем указатель КОНЦА списка
    Foot:=P;
    end
  else
    begin
    List.Wday:=A[1];
    List.Month:=A[2];
    List.MonthN:=StrToInt(A[3]);
    List.Time:=A[4];
    List.Yea:=A[5];
    List.Duration:=StrToInt(A[6]);
    List.IP:=A[7];
    List.CODE:=A[8];
    List.Bytes:=StrToInt(A[9]);
    List.Metod:=A[10];
    List.URL:=A[11];
    List.Client:=A[12];
    List.IerarcheCode:=A[13];
    List.TypeInfo:=A[14];
    List^.Next:=NIL;
    List^.Prev:=NIL;
    //Устанавливаем указатели НАЧАЛА и КОНЦА списка
    Head:=List;
    Foot:=List;
    end;
end;

procedure TForm1.CreateList(List: Plog);
begin
//Создаём "голый" список
New(List);
List.Next:=NIL;
List.Prev:=NIL;
end;


procedure TForm1.DelToList(List,kyrsor: Plog);
begin
//обработка удаления
end;

procedure TForm1.ViewList(List: Plog; i: integer);
begin
while List<>nil do
  begin
    StringGrid1.Cells[1,i]:=List^.Wday;
    StringGrid1.Cells[2,i]:=List^.Month;
    StringGrid1.Cells[3,i]:=IntToStr(List^.MonthN);
    StringGrid1.Cells[4,i]:=List^.Time;
    StringGrid1.Cells[5,i]:=List^.Yea;
    StringGrid1.Cells[6,i]:=IntToStr(List^.Duration);
    StringGrid1.Cells[7,i]:=List^.IP;
    StringGrid1.Cells[8,i]:=List^.CODE;
    StringGrid1.Cells[9,i]:=IntToStr(List^.Bytes);
    StringGrid1.Cells[10,i]:=List^.Metod;
    StringGrid1.Cells[11,i]:=List^.URL;
    StringGrid1.Cells[12,i]:=List^.Client;
    StringGrid1.Cells[13,i]:=List^.IerarcheCode;
    StringGrid1.Cells[14,i]:=List^.TypeInfo;
//    List:=List^.Next;
    i:=i+1;
//    ViewList(List,i);
    ViewList(List^.Next,i);
  end;
end;

procedure TForm1.VivodClick(Sender: TObject);
var
f: TextFile;
P: Plog;
i,k,r: integer;
S: String;
A: ST;
z: boolean;
begin

AssignFile(f,'C:\Documents and Settings\qwerty\Рабочий стол\CAOD\access.log');
Reset(f);  //Открытие файла на чтение
k:=1;

StringGrid1.ColCount:=15;
StringGrid1.RowCount:=1;
//Самое первое поле
StringGrid1.ColWidths[0]:=10;
//Поле Символьный день недели
StringGrid1.Cells[1,0]:='DAY';
StringGrid1.ColWidths[1]:=30;
//Поле Месяц числом
StringGrid1.Cells[2,0]:='MONTH';
StringGrid1.ColWidths[3]:=10;
//Поле Месяц словом
StringGrid1.Cells[3,0]:='MONTH';
//Поле Месяц числом
StringGrid1.Cells[4,0]:='TIME';
//Поле Year
StringGrid1.Cells[5,0]:='YEAR';
//Поле duration
StringGrid1.Cells[6,0]:='DURATION';
//Поле IP
StringGrid1.Cells[7,0]:='IP';
StringGrid1.ColWidths[7]:=75;
//Поле Результирующий Код
StringGrid1.Cells[8,0]:='RESULT CODE';
StringGrid1.ColWidths[8]:=100;
//BYTES
StringGrid1.Cells[9,0]:='BYTES';
//request method
StringGrid1.Cells[10,0]:='REQUEST METHOD';
//Поле URL
StringGrid1.Cells[11,0]:='URL';
StringGrid1.ColWidths[11]:=330;
//Поле Информация о клиенте
StringGrid1.Cells[12,0]:='CLIENT';
StringGrid1.ColWidths[12]:=10;
//Поле Код иерархии
StringGrid1.Cells[13,0]:='HIERARCHY CODE';
StringGrid1.ColWidths[13]:=125;
//Поле Тип содержимого
StringGrid1.Cells[14,0]:='TYPE';
StringGrid1.ColWidths[14]:=125;

CreateList(Tlog);
//Считываем файл по строчно
//while not EOF(f) do
while (StringGrid1.RowCount<=500) do
  begin
  //Открывем файл на чтение
  Read(f,S);
  //Очищаем на временный массив
  for i:=1 to k do
    A[i]:='';

  i:=1;
  r:=0;
  k:=1;
  //Начинаем разбирать считанную строку на слова и запихивать в НАШ СПИСОК
  while i<=length(S) do
    begin
    if (S[i]<>' ') then
      begin
      r:=1;
      A[k]:=A[k]+S[i];
      end
      else
        if r=1 then
          begin
          r:=0;
          k:=k+1;
          end;
    i:=i+1;
    end; { while i<=length(S) }
  Readln(f); //Переходим на новую строку

  AddToList(Tlog,A);

{  //Выводим на экран
  for i:=1 to k do
    StringGrid1.Cells[i,StringGrid1.RowCount]:=A[i]; }

  StringGrid1.RowCount:=StringGrid1.RowCount+1;
  end;

  ViewList(Head,1);

CloseFile(f);
end;

end.



    Суть работы программы такой она хватает файлик и начинает по строчно считывать из него данные. Считав строку она каждое слово строки загоняет в массив и потом уже этот массив заноситься в двусвязный список(мне пока так удобней чем сразу непосредственно в список загонять). Так вот далее я просто тупо пытаюсь вывести этот список на экран в поля объекта StringGrid1.
    Пока в данный момент времени программа считывает только первые 500 строк, а не весь файл, потому что он 190Мб и дальше я буду учиться сортировать эти данные по различным атрибутам, удалять/добавлять/изменять строки. но это ещё рано т.к. не могу разобраться с синтаксисом и работой с указателями.

Не моглибы помочь где ошибка в синтаксисе и в логике.
Софт должен быть открытым, а девушки - бесплатными и доступными, желательно под пиво. :D

Offline Konstantine

  • Full Member
  • ***
  • Posts: 184
  • Karma: +1/-7
Re: Delphi, работа с двусвязными списками
« Reply #1 on: September 01, 2010, 14:43:52 »
Сейчас пока победил проблему работы программы вот этим, с алгоритмом так и не разобрался:

Code: [Select]
я подставил в процедуре
procedure TForm1.AddToList(List: Plog; A: ST);
var P: Plog;
begin
  if List<>nil then
    begin
    New(P);
    P.Wday:=A[1];
    P.Month:=A[2];
    P.MonthN:=StrToInt(A[3]);
    P.Time:=A[4];
    P.Yea:=A[5];
    P.Duration:=StrToInt(A[6]);
    P.IP:=A[7];
    P.CODE:=A[8];
    P.Bytes:=StrToInt(A[9]);
    P.Metod:=A[10];
    P.URL:=A[11];
    P.Client:=A[12];
    P.IerarcheCode:=A[13];
    P.TypeInfo:=A[14];
    P^.Next:=Nil;
    P^.Prev:=List.Next;
    List^.Next:=P.Prev;
    Foot:=P;
    end
  else
    begin
    New(List); // <<<<<<------ вот что я подставил....
    List.Wday:=A[1];
    List.Month:=A[2];
    List.MonthN:=StrToInt(A[3]);
    List.Time:=A[4];
    List.Yea:=A[5];
    List.Duration:=StrToInt(A[6]);
    List.IP:=A[7];
    List.CODE:=A[8];
    List.Bytes:=StrToInt(A[9]);
    List.Metod:=A[10];
    List.URL:=A[11];
    List.Client:=A[12];
    List.IerarcheCode:=A[13];
    List.TypeInfo:=A[14];
    List^.Next:=NIL;
    List^.Prev:=NIL;
    Head:=List;
    Foot:=List;
    end;
end;

+ при пошаговой отработке алгоритма я заметил что в процедуру не передаётся Список Tlog, т.е. если первый раз Tlog сохдаётся он пуст и равен = null и он сам непосредственно заполняется данными, то второй раз при заходе в этой процедуре при проверке if List<>nil then список опять оказывается пустым, как будто он не передаётся в процедуру через аргумент....
Софт должен быть открытым, а девушки - бесплатными и доступными, желательно под пиво. :D

Offline Konstantine

  • Full Member
  • ***
  • Posts: 184
  • Karma: +1/-7
Re: Delphi, работа с двусвязными списками
« Reply #2 on: September 01, 2010, 16:45:33 »
Всё пока разобрался.
Софт должен быть открытым, а девушки - бесплатными и доступными, желательно под пиво. :D