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

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

Как узнать следующее вхождение pos-a


Страницы:   1 2 3

WebSQLNeederrr ©   (2008-06-07 17:50:00) 

Единственное что приходит на ум это следующий алгоритм (задача найти второй пробел в предложении - то есть начало третьего слова):

i:=pos(str,' ');
substr:=copy(str,i,length(str)-i);
i:=pos(substr,' ');

Может есть более простой способ?


Тын-Дын   (2008-06-07 19:58:00) [21]


> WebSQLNeederrr   (07.06.08 19:11) [21]
> Если не сложно посмотрите что можно оптимизировать. Меня
> интересует быстродействие так как строк будет много:


var
 s: String;
 Cnt: Integer;
 PSrc: PChar;
begin
 s:='Не будет радость в каждом звуке';
 PSrc := PChar(s);
 Cnt := 0;
 PSrc := AnsiStrPos(PSrc,' ');
 while Psrc<>nil do
 begin
   PSrc := AnsiStrPos(PSrc,' ')+1;
   if PSrc=PChar(1) then Break;
   Inc(Cnt);
 end;
 ShowMessage(intToStr(Cnt));


Тын-Дын   (2008-06-07 19:28:00) [22]


> Как узнать следующее вхождение pos-a


Например
function SearchString(const FindStr, SourceString: String;Num: Integer):Integer;
var
 FirstSym: PChar; //Ссылка на первый символ

function MyPos(const FindStr, SourceString: PChar;Num: Integer): PChar;
begin
  Result:=AnsiStrPos(SourceString,FindStr);//Поиск вхождения подстроки в строку
  if (Result=nil) then Exit; //Подстрока не найдена
  Inc(Result); //Смещаем указатель на следующий символ
  if Num=1 then Exit; //Если нужно первое вхождение - заканчиваем
  if num>1 then Result := MyPos(FindStr,Result,num-1);
   //Рекурсивный поиск следующего вхождения
end;

begin
 FirstSym := PChar(SourceString);
   //Присваиваем адрес первого символа исходной строки
 Result := MyPos(PChar(FindStr),PChar(SourceString),Num) - FirstSym;
   //Номер позиции в строке
 if Result<0 then Result := 0; //Возвращаем номер позиции
end;


WebSQLNeederrr   (2008-06-07 19:28:00) [23]


> Поросенок Винни-Пух

Спасибо за ссылки!


WebSQLNeederrr   (2008-06-07 19:11:00) [24]

Если не сложно посмотрите что можно оптимизировать. Меня интересует быстродействие так как строк будет много:

function CountWord(str:string):integer;
var i,j:integer;
begin
 i:=0; j:=0;
 while posEX(' ',str,i)<>0 do
 begin
   i:=posEx(' ',str,i);
   inc(i);
   inc(j);
 end;
 CountWord:=j;
end;

procedure TForm1.Button3Click(Sender: TObject);
var s,str:string;i,j:integer;
begin
s:='Не будет радость в каждом звуке';
j:=0;
Randomize;
for i:=1 to Random(CountWord(s)) do
begin
 j:=posEx(' ',s,j);
 j:=j+1;
end;
 s:=copy(s,0,j-1)+' СЛОВО '+copy(s,j-1,length(s)-j+2);
 showmessage(s);
end;


Поросенок Винни-Пух   (2008-06-07 18:55:00) [25]

сам модуль здесь
http://regexpstudio.com/TRegExpr/TRegExpr.html


Поросенок Винни-Пух   (2008-06-07 18:54:00) [26]

http://programania.com/rex.htm

положи модуль в папку коммон и забудь навсегда про кошмары и головную боль  с позами и циклами.

Ну, тут не та задача, в которой нельзя без регулярки, IMHO.

Как раз та самая.


WebSQLNeederrr   (2008-06-07 18:51:00) [27]


> Expression := '\S+\s+(\S+)(\s+)\S+';


А где можно почитать как оно формируется ... Ато какая то китайская азбука для меня эти регулярные выражения ...

PS. Спасибо за вариант.


ProgRAMmer Dimonych   (2008-06-07 18:50:00) [28]

> WebSQLNeederrr   (07.06.08 18:47) [14]
> > P.S. Кстати, а как будет быстрее?
> > 1) Str:=Copy(Str,i,Length(Str)-i);
> > или
> > 2) Delete(Str,1,i);
> > P.P.S. Я за второй вариант :)
> Возможно, но только в том случае когда оригенальную строку
> использовать в будущем не нужно будет ...
Ну, ясное дело. Это так, навеяло...

> Поросенок Винни-Пух ©   (07.06.08 18:48) [15]

Ну, тут не та задача, в которой нельзя без регулярки, IMHO.


WebSQLNeederrr   (2008-06-07 18:49:00) [29]

написал а потом прочитал что у меня ведь тоже затирается эта строка :)


Поросенок Винни-Пух   (2008-06-07 18:48:00) [30]

with TRegExpr.Create do
try
 Expression := '\S+\s+(\S+)(\s+)\S+';
 if Exec('   папа     мыл    соседку') then
  begin
   ShowMessage(Match[1]);
   ShowMessage(IntToStr(MatchPos[2]));
  end;
finally
 Free;
end;


WebSQLNeederrr   (2008-06-07 18:47:00) [31]


> P.S. Кстати, а как будет быстрее?
>
> 1) Str:=Copy(Str,i,Length(Str)-i);
>
> или
>
> 2) Delete(Str,1,i);
>
> P.P.S. Я за второй вариант :)


Возможно, но только в том случае когда оригенальную строку использовать в будущем не нужно будет ...


ProgRAMmer Dimonych   (2008-06-07 18:45:00) [32]

> {RASkov} ©   (07.06.08 18:42) [11]

Ну, мы так от конкурентов избавимся :) Зачем ему RxLib? Батонокидательством и так научат, а ради строковых функций - так их и самому написать можно. Кстати, полезно даже.


ProgRAMmer Dimonych   (2008-06-07 18:44:00) [33]

> WebSQLNeederrr   (07.06.08 18:37) [8]
> Кстати а как заранее узнать сколько всего пробелов в строке?
>  тоже пройтись posEx? Просто я хочу в рендомный пробел вставить
> слово. Тогда получится, что дважды циклом нужно бежаться
> - сначала пробежаться узнать количество пробелов, а потом
> дойти до рендомного пробела ...

Ты, IMHO, на вызовах функции больше времени потеряешь. Быстрее, наверное, будет просто линейно пробежаться по строке и посчитать.

P.S. Кстати, а как будет быстрее?

1) Str:=Copy(Str,i,Length(Str)-i);

или

2) Delete(Str,1,i);

P.P.S. Я за второй вариант :)


{RASkov}   (2008-06-07 18:42:00) [34]

> [5] WebSQLNeederrr   (07.06.08 18:25)
> А что за библиотека RxLib - это встроенная

Не встроенная, а отдельно...

> i:=pos(str,' ');
> i:=posEx(str,' ',i);

i:=0;
.....
i:=posEx(str, #32, i);


> [7] WebSQLNeederrr   (07.06.08 18:32)

Найди RxLib.... не мучайся.... Там есть такие функции, как:
WordCount()
ExtractWord()
и д.р...
Сейчас у меня нет под рукой Rx, поэтому в названиях мог ошибиться, но смысл остается тот же....


WebSQLNeederrr   (2008-06-07 18:41:00) [35]

А как? Что посоветуете?


Поросенок Винни-Пух   (2008-06-07 18:37:00) [36]

конечно криво. особенно если
'  мама мыла папу'
или
'папа   мыл соседку'


WebSQLNeederrr   (2008-06-07 18:37:00) [37]

Кстати а как заранее узнать сколько всего пробелов в строке? тоже пройтись posEx? Просто я хочу в рендомный пробел вставить слово. Тогда получится, что дважды циклом нужно бежаться - сначала пробежаться узнать количество пробелов, а потом дойти до рендомного пробела ...


WebSQLNeederrr   (2008-06-07 18:32:00) [38]

Ну вот реализовал таким способом, но ИМХО как то криво

procedure TForm1.Button3Click(Sender: TObject);
var s,str:string;i,j:integer;
begin
s:='Не будет радость в каждом звуке;
j:=0;
for i:=1 to 2 do
begin
 j:=posEx(' ',s,j);
 j:=j+1;
end;
 j:=j-1;
 showmessage(inttostr(j));
end;


Поросенок Винни-Пух   (2008-06-07 18:27:00) [39]

а нафик тебе тогда первыйпоз, если для поиска второго вхождения ты не знаешь результата первого поз?


WebSQLNeederrr   (2008-06-07 18:25:00) [40]

Спасибо. У меня какраз Д7. Только не совсем понятно параметр оффсет. Я сначала думал это какраз номер вхождения, но если я не ошибаюсь то это просто отступ с какой позиции начинать поиск ... так что даже не знаю чем она пригодится. Разве что сделать так

i:=pos(str,' ');
i:=posEx(str,' ',i);

Я надеялся что есть готовая функция. А что за библиотека RxLib - это встроенная или в инете искать нужно?


Страницы:   1 2 3

Наверх

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