Сравнение подстановочных знаков DELPHI (5-е издание)
Автор: Ли Цзюньюй
электронная почта: [email protected] 2003.1.5
Я думал, что в DELPHI нет готовой функции для подстановочных знаков, но потом я нашел MatchesMask(). Прежде чем я нашел эту функцию, я создавал специальную функцию, чтобы реализовать эту функцию, когда я был в свободном состоянии и все еще в настроении.
Алгоритм работы программы более сложен. Сначала добавьте '?' в конце подстроки. *', затем прочитайте подстроку, найдите символы между подстроками в подстроке, то есть подстроку в подстроке, а затем выполните поиск в исходной строке, чтобы узнать, содержит ли она подстроку в подстроке. реализация по-прежнему дорогая. Эта функция реализует следующие функции:
1. В большинстве случаев это может быть быстрее, чем рекурсивный алгоритм и MatchesMask();
2. Реализовано правильное сравнение звездочек и вопросительных знаков во всех случаях //На проверку может потребоваться время;
3. Поддержка китайского языка //Звездочки и вопросительные знаки должны быть на английском языке, чтобы быть действительными;
4. Поддерживает выбор с учетом регистра.
Обратите внимание, что существует разница между добавлением звездочек в начале и конце подстроки. Этот алгоритм может быть похож на функцию, реализованную с использованием рекурсивного алгоритма в стеке, но на самом деле он несколько отличается от рекурсии. В большинстве случаев он может быть быстрее, чем рекурсивный процесс. Насколько быстрее — сложно. ? Конечно. По крайней мере, есть такая оценка: когда сравнение с подстановочными знаками используется только для поиска подстрок, например, исходная строка — «1111111111», а подстрока — «*11111112*», временная сложность использования рекурсивного алгоритма равна O(N*M ), но я написал Затем эта функция будет упрощена до уровня примерного вызова функции POS() несколько раз. Возможно, POS() в DELPHI можно представить как «алгоритм Кнута-Морриса-Пратта (KMP)» O(N+M) ниже. . Сравнение скорости с рекурсивным алгоритмом не является очевидным для небольшого количества раз. Когда исходная строка имеет 100 последовательных единиц, а подстрока имеет 99 последовательных единиц и, наконец, добавляется символ 2, после тестирования в 1000-кратном цикле это на несколько секунд быстрее, чем рекурсивный алгоритм, и на 20 секунд быстрее, чем MatchesMask(). функция. секунды. Мои фактические многочисленные тесты показывают, что все три иногда являются самыми быстрыми, но MatchesMask() в большинстве случаев кажется медленнее, и скорость рекурсии сильно варьируется. Функция, которую я написал, может быть средней по скорости. Просто функции, которые я написал, предназначены только для справки. Я не несу ответственности за любые проблемы, если они возникнут.
функция isABClikeAX(const abc,ax:widestring):boolean file://abc — это исходная строка, а ax — подстрока;
вар
abcstart,axstart,abclength,axlength:целое число;
endpartabc, endpartax, subax:widestring;
темп, abcwww, axwww: целое число;
начать файл://ааа
температура:=0;
абкстарт: = 1;
аксстарт:=1;
аксwww:=1;
абввв:=1;
abclength: = длина (abc);
длина оси: = длина (топор);
isabclikeax:=истина;
while axstart<=axlength do//Когда длина исходной строки больше или равна подстроке
начать//ббб
если abcstart> abclength, то
начинать
если (ax[axlength]='*') и (axlength=axstart), то isabclikeax:=true
else isabclikeax:=false;//Когда подстрока длиннее исходной строки
перерыв;
конец;
если ax[axstart]='?' тогда
начинать
вкл (axstart);
вкл (abcstart);
продолжать;
конец;
если ax[axstart]='*', то
начинать
вкл (axstart);
температура:=1;
axwww:=axstart;
abcwww:=abcstart;
продолжать;
конец;
если нет((ax[axstart]='?') или (ax[axstart]='*') ), то
начать//ccc
endpartax:=copy(ax,axstart,axlength-axstart+1)+'?*';
subax:=copy(endpartax,1,min(pos('?',endpartax),pos('*',endpartax))-1);
axstart:=axstart+min(pos('?',endpartax),pos('*',endpartax))-1;
endpartabc:=copy(abc,abcstart,abclength-abcstart+1);
если ((pos(subax,endpartabc)<>0) и (temp=1)) или ((pos(subax,endpartabc)=1) и (temp=0)) то
начать//ддд
если temp=1, то temp:=0;
abcstart:=abcstart+(pos(subax,endpartabc)+length(subax)-1) ;
конец // ддд
еще//ддд
начать//ддд
если (temp=0) и (axwww>1), то
начинать
axstart:=axwww;
abcwww:=abcwww+1;
abcstart:=abcwww;
температура:=1;
продолжать;
конец;
isabclikeax:=false;
перерыв;
конец;//ддд
конец;//ccc
конец;//ббб
if (result) and (abcstart<=abclength) and (ax[axlength]<>'*') then isabclikeax:=false;//Когда исходная строка длиннее, чем подстрока
конец;//ааа
ФУНКЦИЯ IsLike(abc,ax:string):boolean file://функция с учетом регистра;
начинать
islike:=isABClikeAX(abc,ax);
конец;
ФУНКЦИЯ WideCard(abc,ax:string):boolean file://функция без учета регистра;
начинать
abc:=прописные буквы(abc);
топор: = верхний регистр (топор);
Widecard: = isABClikeAX (abc, топор);
конец;
Обратите внимание на USES MATH, поскольку используется MIN(), вы также можете использовать оператор IF для замены MIN(), но это недостаточно ясно.
Спасибо некоторым пользователям сети за то, что они дали мне некоторые правильные идеи, которые помогли мне внести изменения в правильном направлении.