![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как узнать следующее вхождение pos-a
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 - это встроенная или в инете искать нужно?