Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.01.2010, 14:23   #1
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию Быстрое удаление дублирующихся слов :).

В общем имеется некое количество конструкций языка программирования. Большинство из них многословные, причем слова могут повторяться между собой, например:
Цитата:
создадим переменную Х
создадим локальную переменную Х
создадим массив У
Так вот, я их всех собрал в одну большую строку (ну порядка 500-600 слов). Теперь мне надо удалить все повторяющиеся - в данном примере оставить создадим переменную локальную массив.
У меня есть такие операции, для которых строка это множество слов (и даже есть операция приведения строки ко множеству - то есть удаления дублирующихся элементов). Но они неэффективны при большом числе слов, при старте программы происходит задержка в несколько секунд, это довольно-таки долго. Сравнимо с загрузкой Ворда, при функциях чуть ли не обычного Блокнота. Какие будут предложения?
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 28.01.2010, 14:36   #2
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

В голову приходит только следующее:
1) Вносим все слова в массив,
2) Обрабатываем массив на повторения, получаем номера слов в отдельный массив.
3) В цикле идем по всем словам, которые повторяются (обращаясь к их номерам из массива):
Код:
For N:=0 to Length(M2)-1 do
 While Pos(M1[M2[N]],S)<>0 do Delete(S,Pos(M1[M2[N]],S), Length(M1[M2[N]]));
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 28.01.2010, 14:46   #3
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Да, я держу такой вариант как крайний случай .
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 28.01.2010, 14:52   #4
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

А нет возможности удалять повторы при получении строки (ввода или что там?). Например, когда вводится слово - копировать его и в нормальную строку и в ту, "урезанную". Но в "урезанную", только, если его там еще нет.
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 28.01.2010, 14:57   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Ну знач и я свои пять коп:
Допустим есть текст в Мемо который нужно "ужать" убрав дубликаты. Тогда код:
Код:
var e,s,q:string;k,i:integer;
begin    q:='';
 for i:=0 to Memo1.Lines.Count-1 do begin
  e:=trim(Memo1.Lines[i])+' ';
  k:=pos(' ',e);
  while k<>0 do begin
   s:=copy(e,1,k);
   if pos(s,q)=0 then q:=q+' '+s;
   delete(e,1,k);
   k:=pos(' ',e);
  end;
 end;
 caption:=q;
end;
Будет достаточно прост и оптимален для этой задачи, так как основные функции в нем ассемблерные.
И никакого лишнего массива
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 28.01.2010, 14:58   #6
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Сообщение от Alex Cones Посмотреть сообщение
А нет возможности удалять повторы при получении строки (ввода или что там?). Например, когда вводится слово - копировать его и в нормальную строку и в ту, "урезанную". Но в "урезанную", только, если его там еще нет.
Затраты будут те же. Все равно это надо делать при старте проги. Сначала определить не могу, была бы такая возможность - я бы задал сразу константу без дубликатов. Проблема в том, что при загрузке нельзя сказать будут ли слова те же самые или нет (допустим кому-то захочется перейти на английский).

Цитата:
Сообщение от Stilet Посмотреть сообщение
Ну знач и я свои пять коп:
Ну я как потестю оба варианта, отпишусь какой лучше.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика

Последний раз редактировалось Utkin; 28.01.2010 в 15:05.
Utkin вне форума Ответить с цитированием
Старый 28.01.2010, 21:51   #7
maxionans
Форумчанин
 
Аватар для maxionans
 
Регистрация: 02.01.2010
Сообщений: 254
По умолчанию

А еще можно задействовать функцию StringReplace:
Код:
  NewString := WordToRemove + StringReplace( 
    OldString, {Строка, в которой нужно удалить повторяющиеся слова}
    WordToRemove, {Слово, которое нужно удалить}
    '', {Пустая строка - заменяет удаляемое слово}
    [ rfReplaceAll, rfIgnoreCase ] {Удаляем все вхождения слова, игнорируя регистр}
  );
maxionans вне форума Ответить с цитированием
Старый 29.01.2010, 06:20   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

ну и я свои 5 копеек добавлю... попробуйте на скорость и такой подход:

если в том коде, который разбирает строку на слова (который и формирует "множество"), использовать TStringList:
Код:
var TS : TStringList;
begin
  TS := TStringList.Create;
  TS.Sorted := true;
  TS.Duplicates := dupIgnore;
...
  TS.Append (Очередное_слово);
то в TS будут только уникальные слова.

Только обратите внимание, что при таком решении они будут отсортированы. Если это не устраивает, то такое решение Вам не подходит.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 29.01.2010, 08:55   #9
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
{Слово, которое нужно удалить}
Этих слов будет много, придется вызывать многократно эту функцию, так что этот подход прироста скорости не даст.

Цитата:
Serge_Bliznykov
Все верно, но тут маленькое но - твоя идея предполагает добавлять слова либо сразу при вводе, либо распарсивать построчно уже готовый текст. Это не сложно, но по-моему на скорость повлияет.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 29.01.2010, 09:25   #10
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Все слова заданы в одной строке, если бы я мог их контролировать при вводе - я бы просто не допустил такую строку. Это служебная информация - которая выдается интерпретатором по требованиям редактора подсветки. Интерпретатор - это объект определенного класса. Редактор создает интерпретатор, тот инициализируется (загружает наименования своих команд, имена функции и т.д. из внешних файлов). Таким образом, я не знаю какую строку получу при следующем запуске - пользователь может сменить синтаксис команд языка - сделать например английские наименования команд или вообще использовать иероглифы для китайцев.

Цитата:
если в том коде, который разбирает строку на слова (который и формирует "множество"), использовать TStringList:
В том юните только процедуры и функции и никаких ссылок на сторонние классы. В общем все берется из модуля System и моих юнитов.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика

Последний раз редактировалось Utkin; 29.01.2010 в 09:46.
Utkin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Удаление повторяющихся слов C vivo89 Помощь студентам 2 24.12.2009 09:18
Удаление слов из строки. grave123 Общие вопросы C/C++ 2 20.12.2009 15:01
Удаление слов из строки С vivo89 Помощь студентам 4 13.11.2009 22:13
Быстрое удаление содержимого ячеек gadspider Microsoft Office Excel 11 18.07.2009 12:08
удаление одинаковых слов (С/С++) jewel Помощь студентам 1 12.12.2008 15:14