:: Visual Foxpro, Foxpro for DOS
Как коротко проверить, что в строке есть хоть один символ из списка
Ydin

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
Это вопрос с ответом.
m.lcList = [qwerty]
m.lcString = [123456789y]
?NOT m.lcString == chrtran(m.lcString,m.lcList,'')
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
akvvohinc

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Есть у меня такая функция, я еще добавил 3-й параметр, чтобы учитывать/не учитывать чувствительность к регистру.
Есть и аналогичная укороченная - узнать, есть ли в строке цифры - для нее lcList задавать не требуется.

PS
Правда, моя чуток покороче, пока не буду писать, за счет чего.



Исправлено 2 раз(а). Последнее : akvvohinc, 19.05.20 02:59
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
of63
Автор

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Можно длину строки сравнивать, до CHRTRAN и после.
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
akvvohinc

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
of63
Можно длину строки сравнивать, до CHRTRAN и после.

Можно, но от этого она ни короче, ни быстрее работать не будет (хотя насчет скорости надо проверять - само сравнение чисел должно быть быстрее, чем строк, но 2 лишние функции...).



Исправлено 1 раз(а). Последнее : akvvohinc, 19.05.20 19:23
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Это такой швендель для чего может пригодиться? Для подбора пароля чи шо?

Можно привести какой-нибудь пример, когда такое будет полезно узнать - есть ли в строке хоть один символ из списка?
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
akvvohinc

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Посмотрел у себя - чаще всего эта функция вызывается для проверки строки параметров на наличие каких-то конкретных (не обязательно одного). Причем, параметры могут быть заданы как русскими, так и графически похожими латинскими буквами:
? instr('КK',m.string)

Еще в одном месте нашел ее вызов, проверяющий, есть ли у имени файла что-то кроме имени, таким способом:
? instr(':\',m.xlsfile)

Ну, и при обработке каких-то полей с особыми свойствами - например, надо проверить, есть ли в некотором поле - шифре чего-то там - символы ',' или '.':
? instr(',.',m.field)

В общем, это некий "укороченный" аналог проверки вхождения символа в строку для нескольких символов одновременно (хотя бы один из):
? 'A'$m.field OR 'Б'$m.field OR ...

PS
Иногда использую ее даже для проверки вхождения одного символа (для лучшего понимания кода и/или единообразия). Например, является ли поле числовым:
? instr('NYI',VARTYPE(field))
вместо
? VARTYPE(field)$'NYI'
Но это уже на любителя - кому-то понятней второй вариант.



Исправлено 3 раз(а). Последнее : akvvohinc, 19.05.20 20:25
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
akvvohinc

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Ydin
?NOT m.lcString == chrtran(m.lcString,m.lcList,'')
На одну операцию меньше:
? chrtran(m.lcString,m.lcList,'') != m.lcString
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
akvvohinc
Ydin
?NOT m.lcString == chrtran(m.lcString,m.lcList,'')
На одну операцию меньше:
? chrtran(m.lcString,m.lcList,'') != m.lcString
Это всё плохо для больших объёмов. Нельзя "перестраивать" строку постоянно укорачивая её. Фокс просто умрёт...

Вот это не умрёт на много-мегабайтных строках со множеством вхождений искомых символов:
? LEFT(m.lcList, 1) $ CHRTRAN(m.lcString, m.lcList, REPLICATE(LEFT(m.lcList, 1), LEN(m.lcList)))

Вполне можно и конструировать динамически строку вида "1"$m.lcString OR "y"$m.lcString OR ... и исполнять через EVALUATE() - ещё быстрее будет.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
akvvohinc

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Igor Korolyov
Вот это не умрёт на много-мегабайтных строках со множеством вхождений искомых символов:
? LEFT(m.lcList, 1) $ CHRTRAN(m.lcString, m.lcList, REPLICATE(LEFT(m.lcList, 1), LEN(m.lcList)))


Вполне можно и конструировать динамически строку вида "1"$m.lcString OR "y"$m.lcString OR ... и исполнять через EVALUATE() - ещё быстрее будет.
Никогда не задумывался о скорости работы этой функции (применение на мега-строках не планировалось) - только об удобстве использования - поэтому до тестирования "на скорость" дело не доходило.
Но сомневаюсь, что предложенный тобой довольно оригинальный первый вариант мне бы пришел в голову.

Но на достаточно коротких строках он вряд ли "обгонит" "простой" вариант.
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
На строках в 5-10 символов нереально проверить, слишком быстро уж

Думаю что его можно ещё больше оптимизировать, если заменять не все символы на 1-й в шаблоне поиска, а лишь все кроме первого Ну и правда, зачем менять А на А лишний раз
Я не знаю как внутри фокса реализован CHRTRAN - делает ли он вложенные циклы на каждый символ строки поиска, или же строит таблицу трансляции и за 1 проход всё заменяет... Тем более что он явно по разному работает для случая когда 2 и 3 параметры равны по размеру и когда различны. Главное что при совпадении размеров строки поиска и строки замены фокс не будет выполнять множество операций перераспределения памяти (вырезание даже 1 символа потребует создания новой строки, а замена может производится "по месту" - конечно же 1 раз память под новую строку придётся выделять и CHRTRAN-у - для "результата").

Т.е. простое правило - CHRTRAN очень эффективен если строка поиска и строка замены имеют одинаковый размер - иначе эта функция уже не будет быстрее чем STRTRAN.

Оператор $ ещё более эффективен, т.к. ничего нигде не меняет, а лишь ищет - но увы, если искать надо не 2-3-10 символов а 150, то отдельные вызовы скажутся негативно на скорости.

Для "удобства пользования", конечно, это просто оформляется в функцию и вся "сложность реализации" будет спрятана внутри. Правда и скорости это не добавит, т.к. передача параметров и собственно вызов функции это лишние накладные расходы.

Сверх-эффективной может быть лишь реализация такого рода алгоритма на c/asm, но я не думаю что хотя бы у 0,01% фоксовиков когда либо за всю их карьеру возникнет практическая необходимость в такого рода оптимизации


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
of63
Автор

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
() Проверить просто - зациклить проверку в FOR на побольше раз, измерить время, потом замениить строку сравнения на пустой оператор и тоже измерить время. Разница - это и есть скорость выполнения проверки. Бывает, что FOR на порядок больше времени занимает, чем измеряемая строка. Тогда можно повторить физически измеряемую строку раз 10, или 100...
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
akvvohinc

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Igor Korolyov
Думаю что его можно ещё больше оптимизировать, если заменять не все символы на 1-й в шаблоне поиска, а лишь все кроме первого Ну и правда, зачем менять А на А лишний раз

Можно иметь вариант этой функции, используемый в 99% всех реальных случаев (у меня так все 100%), когда какой-то символ можно считать зарезервированным (не может встретиться в строке поиска, например, 0h00), и "превращать" все искомые символы в него.
Это позволит убрать два вызова LEFT(m.lcList, 1):
? 0h00 $ CHRTRAN(m.lcString, m.lcList, REPLICATE(0h00, LEN(m.lcList)))



Исправлено 1 раз(а). Последнее : akvvohinc, 24.05.20 17:21
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
of63
Автор

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
А откуда уверенность, что разрабы фокса заложили в преобразователь CHRTRAN особенные случаи (таблица преобразования такова, чтодлины на входе и на выходе одинаковы)? Или, если процессор содержит команды преобразования строк, то использовать эти команды? Эксперимент по измерению скорости, или мониторинг запросов на выделения памяти, конечно, подтвердит предположения, но закладываться на этот ИИ все равно не очень надежно...
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
akvvohinc
Это позволит убрать два вызова LEFT(m.lcList, 1)
Можно, но не думаю что в общем случае LEFT(,1) будет самым медленным звеном Даже в 2-х экземплярах.

of63
А откуда уверенность, что разрабы фокса заложили в преобразователь CHRTRAN особенные случаи
Ну так он согласно документации по разному работает "если есть соответствующий по порядку символ в строке замены и если его нет". Да и общие принципы организации памяти в компьютере позволяют с уверенностью разделять случаи когда надо просто заменить байтики, или когда надо из последовательности что-то убрать, саму последовательность "сжав" - при том что она именно как сишный массив/строка организована, а не как связный список, к примеру.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как коротко проверить, что в строке есть хоть один символ из списка
of63
Автор

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> если есть соответствующий по порядку символ в строке замены и если его нет
Это описание инструкции, логики работы, а не внутреннего устройства функции

> Да и общие принципы организации памяти в компьютере позволяют...
А, может, разрабы, согласно общим принципам программирования, написали подпрограмму "CHRTRAN", которая принимает на вход строку, и возвращает другую строку, всегда, независимо от параметров (таблицы преобразования)? Может на фоксе же её и написали (что было бы свинством)
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 20 (Гостей: 20)

© 2000-2024 Fox Club 
Яндекс.Метрика