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

Вниз

Как проверить есть ли встроке пробел   Найти похожие ветки 

 
Nick   (2008-05-29 16:59) [0]

Как проверить есть ли встроке пробел


 
Сергей М. ©   (2008-05-29 17:01) [1]

ВСтрокеЕстьПробел := Pos("стр ока", " ")>0;


 
han_malign ©   (2008-05-29 17:03) [2]


> Pos("стр ока", " ")

Pos(" ","стр ока") !!!


 
Сергей М. ©   (2008-05-29 17:08) [3]


> !!!


Угу, наоборот)


 
korneley ©   (2008-05-29 17:10) [4]

Я видел у некоторых исполнителей, что-то похожее на

 Memo1.Text := AnsiReplaceStr(MyStr, #32, #13#10);
 ShowMessage("Количество пробелов: " + inttostr(Memo1.Lines.Count));


 
Renegat_   (2008-05-29 18:03) [5]

Для поиска одного символа рекомендую вот это. Работает гораздо быстрее, нежели Pos.

function RChPos(_s:string; _c:Char):DWORD;
asm
 PUSH EBX;
 PUSH EDI;

 // <-- Забивка всего EDX паттерном символа
 MOV DH, DL;
 MOVZX ECX, DX;
 SHL EDX, 16;
 OR EDX, ECX;

 // <-- ЕСХ = длина_строки + 4
 MOV ECX, DWORD PTR [EAX-4];
 ADD ECX, 4;

 @loop:
   ADD ECX, -4;
   JL @nqlp; // <-- Достигнуто начало строки и до сих пор ничего не найдено? Выходим
   MOV EBX, DWORD PTR [EAX+ECX];
   XOR EBX, EDX; // <-- Зануляются все вхождения нужного символа
   LEA EDI, [EBX-01010101h];
   NOT EBX;
   AND EDI, EBX; // <-- 00h-01h=0FFh. NOT(00h) тоже равно 0FFh.
   AND EDI, 80808080h; // <-- Где был 0FFh, там стала единица в знаковом разряде
 JE @loop;

 // <-- Перевод позиции первого включённого бита в позицию символа
 BSF EDI, EDI;
 SHR EDI, 3;
 LEA EAX, [ECX+EDI+1];
 POP EDI;
 POP EBX;
 RET;

 @nqlp:
 POP EDI;
 POP EBX;
 XOR EAX, EAX; // <-- Символа в строке нет - вернём 0
 RET;
end;

ЗЫ Алгоритм, конечно, стар как мир, однако до сих пор эффективен =)


 
Renegat_   (2008-05-29 18:05) [6]

вызывать так:
i:=RChPos(str_to_find_spaces, " ");

обход строки идёт с конца. Поэтому возвернётся не первый пробел в строке, а последний. Однако для проверки наличия - сойдёт...


 
Johnmen ©   (2008-05-29 18:50) [7]

Ага. А здесь ещё быстрее http://fastcode.sourceforge.net
Так быстро, что ты отдыхаешь :))
И что дальше?


 
Renegat   (2008-05-31 13:46) [8]

> Так быстро, что ты отдыхаешь :))

Уважаемый господин Johnmen, Вы оскорбили меня в лучших чувствах! +)
Если бы Вы соблаговолили посмотреть код функций POS и иже с ними из этого набора, то Вы увидели бы, что приведённый в данном треде алгос есть не что иное как в несколько раз урезанная и упрощённая модификация того, что представлено на данном сайте. Ибо, как я уже говорил,
> Алгоритм, конечно, стар как мир

Но если уж нужны измерения, то для строки "abcdefghijklmnop" и паттерна "h" за 10^6 проходов самая быстрая в либах Фасткода процедура отработала за 1891 мс, выложенная мной - за 1408 мс. Результат естессно один и тот же - 8. Вывод: йа не отдыхаю, йа работаю %)

ЗЫЖ сорри за флуд.


 
Renegat   (2008-05-31 13:49) [9]

> за 10^6 проходов

10^8, прошу прощения.


 
Sha ©   (2008-05-31 16:26) [10]

> Renegat   (31.05.08 13:49) [9]

Быстрая программа никому не нужна, усли она работает неправильно :)

Я бы не рекомендовал пользоваться функцией приведенной в [5], т.к.:

1. Порядок следования аргументов в ней отличается от стандартной Pos и от фасткодовской CharPos, что может озадачить пользователя.

2. Ее результат имеет тип dword, что также отличается от общепринятого, как следствие, мы получаем варнинги при вычислениях с целыми на операторах вида i:=i+RChPos(s,"1");

3. При использовании этой функции на пустых строках получаем AV.

4. Выполняя следующую последовательность операторов получаем
   6,5,4,3,0,0, вместо 6,5,4,3,2,1:

 ShowMessage(IntToStr(RChPos("123456","6")));
 ShowMessage(IntToStr(RChPos("123456","5")));
 ShowMessage(IntToStr(RChPos("123456","4")));
 ShowMessage(IntToStr(RChPos("123456","3")));
 ShowMessage(IntToStr(RChPos("123456","2")));
 ShowMessage(IntToStr(RChPos("123456","1")));


5. Выполняя следующую последовательность операторов получаем
   4,0,0,0, вместо 0,3,2,1:

 ShowMessage(IntToStr(RChPos("123",#0)));
 ShowMessage(IntToStr(RChPos("123","3")));
 ShowMessage(IntToStr(RChPos("123","2")));
 ShowMessage(IntToStr(RChPos("123","1")));


7. Выполняя следующую последовательность операторов получаем 7 вместо 0:

 s:="123456";
 s:=s+"7";
 SetLength(s,5);
 i:=RChPos(s,"7");
 ShowMessage(IntToStr(i));


8. И, наконец, по поводу скорости. Фасткодовские функции полностью совместимы с RTL и много чего учитывают. Например, они нормально работают со строками нулевой длины даже тогда, когда указатель на данные не равен nil. Поэтому съэкомив на чем-нибудь, можно попытаться их обогнать. Но даже после истравления всех твоих ошибок, уверен, Фасткодовские функции будут обгонять твою на строках порядка 200 знаков. На коротких строках все функции быстры, различие наблюдается в основном из-за несовершенства метода измерения.

Успехов в дальнейшей работе :)


 
Sha ©   (2008-05-31 17:49) [11]

> Renegat   (31.05.08 13:49) [9]

9. Фасткодовсие функции, как и RTL, никогда не читают данные за пределами двойного слова, в котором лежит терминатор. Твоя читает, что может привести к AV. Строить пример мне не хочется, но можешь поверить на слово. А еще лучше скачай соответствуюшие "Validation and Benchmark Tools", там множество тестов.


 
Anatoly Podgoretsky ©   (2008-05-31 18:01) [12]

То есть не функция, а сплошной глюк.


 
Sha ©   (2008-05-31 18:09) [13]

> Anatoly Podgoretsky ©   (31.05.08 18:01) [12]

Согласен. Но парень осваивает ассемблер, а это надо пощрять.

> Renegat   (31.05.08 13:49) [9]

10. Выполняя следующую последовательность операторов получаем 6,5, вместо 6,6:

 ShowMessage(IntToStr(RChPos("123456","6")));
 ShowMessage(IntToStr(RChPos("123466","6")));

Т.е. функция ищет справа, но иногда немножко слева.


 
Renegat   (2008-05-31 18:46) [14]

Печально =(
Мдя. Что МАСМу хорошо, то Делфям смерть...

*ушёл в газенваген, вернусь не скоро*


 
Loginov Dmitry ©   (2008-05-31 19:01) [15]

Малюсенькое замечание по новой PosEx() :))

Раньше (в D7) в PosEx() в качестве индекса можно было передать 0, и он выполнял поиск с начала строки. В D2006 и далее PosEx() отказывается работать, если задать нулевой индекс. Может быть это работает более эффективно, однако появилась несовместимость с предыдущими версиями. Имхо, раньше удобнее было :)



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

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

Наверх




Память: 0.51 MB
Время: 0.019 c
3-1200909104
Karburator
2008-01-21 12:51
2008.06.29
отвязать DBLookupCombobox от управляющего ДатаСурса


2-1212412416
Ceil
2008-06-02 17:13
2008.06.29
Переименование


15-1211209910
Пробегал2...
2008-05-19 19:11
2008.06.29
Скорость движения мыши


15-1211189972
Сергей_А
2008-05-19 13:39
2008.06.29
Отображение VRML


2-1212386391
m
2008-06-02 09:59
2008.06.29
как залогиниться на сайт