Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.11;
Скачать: CL | DM;

Вниз

поиск слова в тексте и удаление его !!!   Найти похожие ветки 

 
Николай,гер   (2005-06-12 01:23) [0]

Доброго времени суток мне нужна программа которая  бы удаляла слова  
в фаиле , которые присутсвуют там неколько раз. Я тут попытался сам такое написать но оно, как вы уже догодалисьс не работает. Может подскажет кто где здесь  ошибка ?
код :
procedure TForm1.BitBtn1Click(Sender: TObject);
var
text,Stext ,aus   : String;
Mystart, Myend: integer;
Found         : integer;
gk             :TSearchTypes;
textlenge ,i,t     :integer;
begin
text:=Richedit1.Text;
aus:="";

textlenge:= length(text);
for i:=0 to textlenge do

begin
t:=0;
repeat
t:=t+1;
until  (" "= Copy(text,t,1));

stext:= Copy (text, 0 ,t);
aus:=aus+stext+ " ";
text := Copy (text,length(stext),textlenge );
Richedit1.Text:=text;
MyStart:=0;
MyEnd := Length(Richedit1.text);
for mystart:=0 to myend do
begin
Found :=Richedit1.FindText(Stext,MyStart,Myend,gk);
if (Found <>-1 ) then

begin

Richedit1.SelStart:=Found;
Richedit1.SelLength:=Length(Stext);
Delete(Text,Found,Length(Stext));
end;

end;
Richedit2.Text:= aus;
end;
end;


 
Германн ©   (2005-06-12 02:08) [1]

Ну на вскидку.
Позиция 0 в строке всегда (в паскале) имела особое значение. Реально не относящееся к "содержимому строки".


 
ssk ©   (2005-06-12 02:10) [2]

брррр........!
может лучше сделать так?

var
 s: string;

RichEdit1.Lines.LoadFromFile();
s:= RichEdit1.Text;
s := StringReplace();
RichEdit1.Text := s;
RichEdit1.Lines.SaveToFile();


 
Николай,гер   (2005-06-12 10:21) [3]

Спасибо за ответы , но у меня Дельфи на этой фунции StringReplace(); ругатся начинает :)

"[Error] Unit1.pas(93): Not enough actual parameters"

какие параметры я должен ей передавать ?

заранее спасибо


 
Плохиш ©   (2005-06-12 10:43) [4]

>Николай,гер   (12.06.05 10:21) [3]

А посмотреть в справке, какие параметры требует функция StringReplace, ну совсем западло?


 
Николай,гер   (2005-06-12 10:57) [5]

нет не запалдо , просто я английским не владею


 
Alx2 ©   (2005-06-12 11:14) [6]

Заводим отсортированный список "запрещенных" слов. Читаем строчку по словам. Ели очередное слово в списке - читем дальше. Иначе, добавляем слово в список и в результат.


 
Николай,гер   (2005-06-12 11:23) [7]

Да нет там запрещённых слов, в том то и дело . Программа должна сама сравнивать все слова которые там находятся и выкидвать их повторы если таковые имеются.

но всё равно спасибо за совет
Да а как конкретно это зделать ?


 
Alx2 ©   (2005-06-12 11:29) [8]

>Николай,гер   (12.06.05 11:23) [7]

>Да нет там запрещённых слов, в том то и дело .

Запрещенными я назвал слова, чьи повторы имеются.
На первом шаге их нет, конечно. А потом появляются.

Если слово лежит в списке запрещенных, значит оно встречалось ранее и вновь встретится не должно.


 
Alx2 ©   (2005-06-12 11:41) [9]

Например:

 function WordsFilter(const S: string): string;
 const // Множество символов, непрерывная цепочка которых есть слово.
   ValidSet = ["a".."z", "A".."Z", "а".."я", "А".."Я", "0".."9"];
 var SLen: Integer;
   function GetWord(var Idx: Integer; var Dust: string): string;
   var Start: Integer;
   begin
     Result := "";
     Start := Idx;
     // Пропускаем мусор
     while (Idx <= SLen) and not (S[Idx] in ValidSet) do Inc(Idx);
     // Мусор пригодится, так как не сказано, что его надо удалять
     Dust := Dust + Copy(S, Start, Idx - Start);
     Start := Idx;
     // Формируем слово
     while (Idx <= SLen) and (S[Idx] in ValidSet) do Inc(Idx);
     Result := Copy(S, Start, Idx - Start);
   end;
 var
   Idx: Integer;
   Word, Dust: string;
 begin
   Result := "";
   with TStringList.Create do
   try
     Duplicates := dupIgnore;
     CaseSensitive := True;
     Sorted := true;
     SLen := Length(S);
     Idx := 1;
     Dust := "";
     while Idx <= sLen do
     begin
       Word := GetWord(Idx, Dust);
       if IndexOf(Word) < 0 then // Если слово не "запрещенное"
       begin
         Add(Word); // То делаем его запрещенным и дописываем в результат.
         Result := Result + Dust + Word;
         Dust := ""; // Мусор сбрасываем, так как он уже попал в результат.
       end;
     end;
   finally
     Free;
   end;
 end;
begin
 // Пример использования
 ShowMessage(WordsFilter("test test1, test1, alpha, beta beta, gamma"));
end;


 
Николай,гер   (2005-06-12 13:02) [10]

Спасибо это то что надо , с этим буду дальше ковырятся :)


 
Anatoly Podgoretsky ©   (2005-06-12 13:14) [11]

Текст загоняется в StringList - Sorted, Ignore Dups


 
Alx2 ©   (2005-06-12 13:35) [12]

>Anatoly Podgoretsky ©   (12.06.05 13:14) [11]

Получится только в частных случаях.


 
Николай,гер   (2005-06-12 13:43) [13]



var
      SL : TStringList;
 
  text: string;
  td:TDuplicates;

begin
td:=dupIgnore;

SL.Duplicates:=td;


это так выглидит ?
если да то оно не работает :(


 
Николай,гер   (2005-06-12 14:18) [14]

ПАсибо всем я её решил и особое спасибо Anatoly Podgoretsky
вот моё решине кому интерестно

//для того что бы можно было использовать TStringList нужно сначала текст ненмого обработать
procedure TForm1.ffnen1Click(Sender: TObject);
var
text,teiltex: string;
i:integer;
begin
Richedit1.Lines.LoadFromFile("mail.rtf");
text:=Richedit1.Text;
teiltex:="";
for i:=0 to length(text) do
begin
 if (" "= text[i])then
   begin
   listbox1.Items.Add(teiltex);// Приходится использовать listbox1 для того что бы записать текст в столбик  а удаление находится в следующей процедуре
   Teiltex:="";
   end
 else Teiltex:=teiltex+ text[i]
end ;
Richedit1.Lines:=ListBox1.Items;
end;

//Следующая процедура которая находит дупликаты и убивает их

procedure TForm1.BitBtn1Click(Sender: TObject);
var
 SL : TStringList;
 text: string;
 td:TDuplicates;

begin

text:=Richedit1.Text;
SL:=TStringList.Create;
SL.Sorted:=true;
td:=dupIgnore; // Это значеине игнорирует все двойник в файле
SL.Duplicates:=td;
SL.Text:=text;

Richedit2.Text:=SL.Text;
end;


 
Anatoly Podgoretsky ©   (2005-06-12 14:21) [15]

Не требуются таких сложных преобразований, для разбивки на слова (то есть чтобы записать в столбик) пользуемся встроеными срествами того же TSrilngList как CommaText, для удаления дублей Sorted и dupIgnore. Никаких других компонент не требуется. Поработай в этом направлении.


 
Alx2 ©   (2005-06-12 15:24) [16]

>Anatoly Podgoretsky ©   (12.06.05 14:21)

Снимаю шляпу.
Я так мысли читать не умею :)


 
Anatoly Podgoretsky ©   (2005-06-12 15:51) [17]

Ну ты и гад, ведь ключат же в штатные телепаторы.


 
имя   (2005-06-12 19:21) [18]

Удалено модератором
Примечание: Смени ник. Запятая в нике недопустима!


 
Николай_герм   (2005-06-12 21:22) [19]

а кто против ?
имеется ввиду :  SL.CommaText:=text;

непремменно попробую.:)


 
Anatoly Podgoretsky ©   (2005-06-12 21:32) [20]

SL.CommaText:=text; или решение с DelimitedText, но для разделеных пробелом и первого хватает.


 
Alx2 ©   (2005-06-12 22:13) [21]

Прикола ради попытал свой код Alx2 ©   (12.06.05 11:41) на полуторамегабайтном файле. Получил EOutOfMemory :-)

Пришлось вместо наращивания Result сделать выкидывание из него. Иначе страшно фрагментируется куча.

Еще есть подозрения, что TStringList придает тормоза вместо ожидаемого ускорения.


 
Просто Джо ©   (2005-06-12 22:26) [22]

> [21] Alx2 ©   (12.06.05 22:13)
Для некоторого (иногда, значительного) устранения "тормозов" можно воспользоваться THashedStringList - там поиск строк реализован гораздо быстрее (через хэщ-таблицы, вероятно). Хотя, придется пожертвовать дополнительной памятью.


 
Alx2 ©   (2005-06-12 22:44) [23]

>Просто Джо ©   (12.06.05 22:26) [22]
Нет, я думаю дело не в скорости поиска, а в способе вставки нового элемента в TStringList.
Там для вставки используется сдвиг элементов массива.
Это занимает alpha*k времени, где k - количество элементов.
Бинарный поиск занимает beta*log(k). Итого время вставки есть
alpha*k + beta*log(k).
При пробеге по различным словам, общее количество которых есть n
получаем, что на вставку уходит beta*n*ln(n)+alpha*n*(n+1)/4+O(1/n) если бы alpha (затраты на вставку) равнялась нулю, все было-бы тип-топ. А так - сложность даже выше квадратичной.

А квадратичную сложность дает простой способ "в лоб":
Берем слово, все его дальнейшие вхождения забиваем мусором (символом, не входдящим в ValidSet).
И так для каждого слова.
Потом "выкидываем мусор" - операция по времени O(length(S)).

При проверке второй способ "в лоб" оказался действительно быстрее. (На 8Mb - в два раза)


 
Alx2 ©   (2005-06-12 22:48) [24]

Вдогонку: "забивку мусором" использовал и в использовании TStringList



Страницы: 1 вся ветка

Текущий архив: 2005.07.11;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.027 c
14-1118826756
sco123
2005-06-15 13:12
2005.07.11
Требуется программист на Delphi


1-1118839667
Faraday
2005-06-15 16:47
2005.07.11
Как скопировать дочернюю форму?


3-1117179499
Гость2
2005-05-27 11:38
2005.07.11
Как просуммровать значения по полю таблицы?


4-1115814772
Неуловимый Джо
2005-05-11 16:32
2005.07.11
API к perfmon


10-1094817786
r_nikola
2004-09-10 16:03
2005.07.11
Глюки с NumberFormat для даты в Excel (понимает только по-русски)