Perbandingan Wildcard DELPHI (Edisi ke-5)
Penulis: Li Junyu
email: [email protected] 2003.1.5
Saya pikir tidak ada fungsi siap pakai untuk wildcard di DELPHI, tapi kemudian saya menemukan MatchesMask(). Sebelum saya menemukan fungsi ini, saya biasa membuat fungsi custom untuk merealisasikan fungsi ini ketika saya dalam keadaan bebas dan masih dalam mood.
Algoritma program ini lebih rumit. Pertama tambahkan '?' di akhir substring. *', lalu baca substringnya, cari karakter di antara karakter wildcard di substring, yaitu substring di substring, lalu cari di string sumber untuk melihat apakah berisi substring di substring masih mahal untuk diterapkan. Fungsi ini mengimplementasikan fungsi-fungsi berikut:
1. Ini mungkin lebih cepat daripada algoritma rekursif dan MatchesMask() dalam banyak kasus;
2. Menerapkan perbandingan tanda bintang dan tanda tanya yang benar dalam semua kasus; //Ini mungkin masih memerlukan waktu untuk diverifikasi
3. Mendukung bahasa Mandarin; //Tanda bintang dan tanda tanya harus dalam bahasa Inggris agar valid
4. Mendukung pemilihan peka huruf besar-kecil.
Perhatikan bahwa ada perbedaan antara menambahkan tanda bintang di awal dan akhir substring. Algoritma ini mungkin mirip dengan fungsi yang diimplementasikan menggunakan algoritma rekursif pada stack, namun sebenarnya agak berbeda. Algoritma ini telah membuat beberapa perbaikan pada rekursi. Ini mungkin lebih cepat daripada proses rekursif dalam banyak kasus ? Tentu. Setidaknya ada perkiraan ini: ketika perbandingan wildcard hanya digunakan untuk mencari substring, misalnya string sumber adalah "1111111111" dan substringnya adalah "*11111112*", kompleksitas waktu penggunaan algoritma rekursif adalah O(N*M ), tapi saya menulis Fungsi ini kemudian akan disederhanakan menjadi kompleksitas waktu yang kira-kira memanggil fungsi POS() beberapa kali. Mungkin POS() di DELPHI dapat dibayangkan sebagai "algoritma Knut-Morris-Pratt (KMP)" O(N+M) di bawah ini . Perbandingan kecepatan dengan algoritma rekursif tidak terlihat jelas untuk beberapa kali. Ketika string sumber memiliki 100 1 berturut-turut dan substring memiliki 99 1 berturut-turut dan akhirnya karakter 2 ditambahkan, setelah pengujian dalam perulangan 1000 kali, ini beberapa detik lebih cepat daripada algoritme rekursif dan 20 detik lebih cepat daripada MatchesMask() fungsi. Beberapa pengujian saya yang sebenarnya menunjukkan bahwa ketiganya terkadang yang tercepat, tetapi MatchesMask() tampaknya lebih lambat di sebagian besar waktu, dan kecepatan rekursi sangat bervariasi. Fungsi yang saya tulis mungkin kecepatannya rata-rata. Hanya saja fungsi-fungsi yang saya tulis hanya untuk referensi saja. Saya tidak bertanggung jawab jika terjadi masalah.
function isABClikeAX(const abc,ax:widestring):boolean; file://abc adalah string sumber dan ax adalah substring
var
abcstart,axstart,abclength,axlength:integer;
endpartabc,endpartax,subax:widestring;
temp,abcwww,axwww:integer;
mulai file://aaa
suhu:=0;
abcmulai:=1;
awalan kapak:=1;
kapakwww:=1;
abcwww:=1;
abcpanjang:=panjang(abc);
panjang sumbu:=panjang(kapak);
isabclikeax:=benar;
while axstart<=axlength do//Ketika panjang string sumber lebih besar atau sama dengan substring
mulai//bbb
jika abcstart> abclength maka
mulai
jika (ax[axlength]='*') dan (axlength=axstart) maka isabclikeax:=true
else isabclikeax:=false;//Ketika substring lebih panjang dari string sumber
merusak;
akhir;
jika ax[axstart]='?' maka
mulai
inc(axstart);
inc(abcstart);
melanjutkan;
akhir;
jika ax[axstart]='*' maka
mulai
inc(axstart);
suhu:=1;
axwww:=axstart;
abcwww:=abcmulai;
melanjutkan;
akhir;
jika tidak((ax[axstart]='?') atau (ax[axstart]='*') ) maka
mulai//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:=salin(abc,abcstart,abclength-abcstart+1);
jika ((pos(subax,endpartabc)<>0) dan (temp=1 )) atau ((pos(subax,endpartabc)=1) dan (temp=0)) maka
mulai//ddd
jika suhu=1 maka suhu:=0;
abcstart:=abcstart+(pos(subax,endpartabc)+panjang(subax)-1) ;
akhir//dd
lain//ddd
mulai//ddd
jika (temp=0) dan (axwww>1) maka
mulai
axstart:=axwww;
abcwww:=abcwww+1;
abcstart:=abcwww;
suhu:=1;
melanjutkan;
akhir;
isabclikeax:=salah;
merusak;
akhir;//dd
akhir;//ccc
akhir;//bbb
if (hasil) dan (abcstart<=abclength) dan (ax[axlength]<>'*') maka isabclikeax:=false;//Ketika string sumber lebih panjang dari substring
akhir;//aaa
FUNGSI IsLike(abc,ax:string):boolean; file://fungsi peka huruf besar/kecil
mulai
seperti:=isABClikeAX(abc,ax);
akhir;
FUNGSI WideCard(abc,ax:string):boolean; file://fungsi tidak peka huruf besar-kecil
mulai
abc:=huruf besar(abc);
kapak:=huruf besar(kapak);
kartu lebar:=isABClikeAX(abc,ax);
akhir;
Perhatikan USES MATH, karena digunakan MIN(), Anda juga dapat menggunakan pernyataan IF untuk menggantikan MIN(), tetapi kurang jelas.
Terima kasih kepada beberapa netizen yang telah memberi saya beberapa wawasan yang benar, yang membantu saya melakukan revisi ke arah yang benar.