Форум: "Начинающим";
Текущий архив: 2008.06.29;
Скачать: [xml.tar.bz2];
ВнизКак проверить есть ли встроке пробел Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.046 c