На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
Страницы: (4) [1] 2 3 ... Последняя » все  ( Перейти к последнему сообщению )  
> Удалить дубликаты строк - Delphi/RAD XE3+
    Ребята, подскажите алгоритм - удаление дубликатов строк через:
    AssignFile
    Reset
    Rewrite
    writeln

    Что то типа такого (поскольку файлы будут по 300 - 700 мегабайт) или ваш вариант:
    ExpandedWrap disabled
      var f1,f2:TextFile;
      s:string;
      i:integer;
      begin
      if OpenDialog1.Execute then begin
      AssignFile(f1,OpenDialog1.FileName);
      AssignFile(f2,ExtractFileDir(OpenDialog1.FileName)+'\del.txt');
      Reset(f1);
      Rewrite(f2);
      while not Eof(f1) do begin
              Readln(f1,s);
       
      // и тут алгоритм удаления.
       
      Writeln(f2,s);
      end;
      CloseFile(f1);
      CloseFile(f2);
      end;
      end
      Схема примерно такая:
      ExpandedWrap disabled
        unical:boolean;
        while not Eof(f1) do
        begin
                Readln(f1,s);
                pos := SavePos(f1); // сохраняем положение на следующей строке
                // и тут алгоритм удаления:
                unical := true; // пока прочитанная строка уникальна
                while not Eof(f1) do
                begin
                Readln(f1,s2); // ещё строку прочитали
                if s=s2 then begin unical :=false; break; end; // копия нашлась - выйдем из цикла while
                end;
                if unical then Writeln(f2,s); // уникальную - запишем
                RePos(f1, pos); // вернёмся на место, где следующая строчка
        end;


      Добавлено
      Метод, конечно, жутко медленный (если строк - N, то время = O(N2)), но как быстрее с файлом провернуть - не знаю.
      Можно было бы прочитать строки, узнать их хэш (CRC32 какой-нибудь), и по нему сверяться в памяти, но тогда мы сразу ныряем в вероятностный исход, а не хотелось бы.
        Цитата Славян @

        Славян спасибо, но почему то подчеркивает ошибки.
        Вот так я сделал (Подскажите как исправить ?):
        ExpandedWrap disabled
          procedure Tfrm_Main.Button1Click(Sender: TObject);
          var f1,f2:TextFile;
          s:string;
          i:integer;
          unical:boolean;
          begin
          if OpenDialog1.Execute then begin
          AssignFile(f1,OpenDialog1.FileName);
          AssignFile(f2,ExtractFileDir(OpenDialog1.FileName)+'\del.txt');
          Reset(f1);
          Rewrite(f2);
          while not Eof(f1) do begin
                  Readln(f1,s);
           
           Readln(f1,s);
                  pos := SavePos(f1); // сохраняем положение на следующей строке
                  // и тут алгоритм удаления:
                  unical := true; // пока прочитанная строка уникальна
                  while not Eof(f1) do
                  begin
                  Readln(f1,s2); // ещё строку прочитали
                  if s=s2 then begin unical :=false; break; end; // копия нашлась - выйдем из цикла while
                  end;
                  if unical then Writeln(f2,s); // уникальную - запишем
                  RePos(f1, pos); // вернёмся на место, где следующая строчка
           
          Writeln(f2,s);
          end;
          CloseFile(f1);
          CloseFile(f2);
          end;
          end
          Скажите, какие ошибки, а то я на Си пишу, подзабыл Паскаль.
          1. SavePos - просто придумалась. В Си есть ftell, коя говорит положение, как в Паскале - не знаю, но тоже что-то есть.
          2. RePos - Тоже придумалась. В Си есть fseek(...), устанавливает положение. Как в Паскале - не знаю, но тоже что-то есть.
          3. Есть ли в Паскале break - не помню. Но выход из цикла как-то делается.
          :blush:

          Добавлено
          Ну и эту pos надо в var завести. Небось, как long или что-то вроде такого.

          Добавлено
          Вторую Writeln(f2,s); уберите.
            Цитата Славян @

            RePos - подчеркивает
            SavePos - подчеркивает
            Пишет: Undeclared identifier: 'RePos'
              s2 надо в объявление добавить.
              Есть в Паскале: pos :=FilePos(f1);
                Славян Ух, я совсем теперь запутался... :).
                  Сейчас раскопаемся!
                  ExpandedWrap disabled
                    AssignFile(f1,FileName);
                        AssignFile(f2,'el.txt');
                        Reset( f1 );
                        Rewrite( f2 );
                        while not Eof(f1) do
                        begin
                            Readln( f1, s);
                            pos := FilePos( f1 ); // сохраняем положение на следующей строке
                            // и тут алгоритм удаления:
                            unical := true; // пока прочитанная строка уникальна
                            while not Eof(f1) do
                            begin
                                Readln( f1, s2); // ещё строку прочитали
                                if s=s2 then begin unical := false; break; end; // копия нашлась - выйдем из цикла while
                            end;
                            if unical then Writeln(f2,s); // уникальную - запишем
                            //Seek(f1, pos); // вернёмся на место, где следующая строчка
                            ResetFile(f1, pos); // вернёмся на место, где следующая строчка
                        end;
                        CloseFile( f1 );
                        CloseFile( f2 );
                    end.
                  Схема такая. ResetFile у меня не пашет. Надо доколдовать.

                  Добавлено
                  Переменная i не нужна.
                    Славян Сделал вот так (pos := FilePos( f1 ); // Подчеркивает что неизвестный индентификатор):
                    ExpandedWrap disabled
                      var f1,f2:TextFile;
                      s,S2:string;
                      i:integer;
                      unical:boolean;
                       
                      begin
                      if OpenDialog1.Execute then begin
                      AssignFile(f1,OpenDialog1.FileName);
                      AssignFile(f2,ExtractFileDir(OpenDialog1.FileName)+'\del.txt');
                          Rewrite( f2 );
                          while not Eof(f1) do
                          begin
                              Readln( f1, s);
                              pos := FilePos( f1 ); // сохраняем положение на следующей строке
                              // и тут алгоритм удаления:
                              unical := true; // пока прочитанная строка уникальна
                              while not Eof(f1) do
                              begin
                                  Readln( f1, s2); // ещё строку прочитали
                                  if s=s2 then begin unical := false; break; end; // копия нашлась - выйдем из цикла while
                              end;
                              if unical then Writeln(f2,s); // уникальную - запишем
                              //Seek(f1, pos); // вернёмся на место, где следующая строчка
                              Reset(f1, pos); // вернёмся на место, где следующая строчка
                          end;
                          CloseFile( f1 );
                          CloseFile( f2 );
                      end;
                       end;
                    Сообщение отредактировано: Kirilis2018 -
                      Ну да, надо в var добавить:
                      pos :longInt;

                      Добавлено
                      А! Seek или ResetFile(f, pos) он хочет для бинарных файлов, а не для текстовых.
                      Надо как-то перевести указатель f1 в бинарный. Как сие в Паскале делать - не ведаю. :'(
                        СлавянДобавил все равно ругается на: Reset(f1, pos); // вернёмся на место, где следующая строчка
                          Цитата Славян @
                          RePos(f1, pos); // вернёмся на место, где следующая строчка

                          Хитрый какой. Для текстовых файлов не катит.

                          У меня какое то странное дежавю про текстовые файлы и 700 мб. :D

                          У меня несколько вариантов:
                          1 Считать весь файл в память, убрать дубли, поместить на диск. Но это не совсем через Reset Rewrite writeln
                          2 по тупому перебирать все сторки и сравнивать. Но это текстовый файл придется бесконца перебирать и чтобы взять последнюю строчку перебирать от начала до предпоследней строчки
                            Так да, это последнее трудное место осталось. Надо спецов по Паскалю спрашивать о переводе. Ну и функция называется ResetFile.

                            Добавлено
                            Цитата ^D^ima @
                            Для текстовых файлов не катит.
                            Ну это прямо=честно не катит. А если обмануть и перевести указатель с текстового на бинарный, то думаю, что скушает на 'ура'. Но вот с переводом - проблема. Подскажите, как там эти чёртовы cast'ы делаются? :blush:
                              ^D^ima,Славян Походу, ребята, задача очень сложная. Вы, намного опытней меня и все равно задумались. А что уже говорить про меня. Но все равно Спасибо человеческое. Если получиться то гуд.
                              Сообщение отредактировано: Kirilis2018 -
                                Ой, Kirilis2018, походу ResetFile указывает каким ему размером стать! Так что не надо её использовать!! Надо Seek докрутить.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0745 ]   [ 17 queries used ]   [ Generated: 19.04.24, 01:28 GMT ]