Untuk blok kode berikut:
For I = 0 To listOfStrings.Count - 1
If myString.Contains(lstOfStrings.Item(I)) Then
Return True
End If
Next
Return False
Outputnya adalah:
Kasus 1:
myString: C:\Files\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: True
Kasus 2:
myString: C:\Files3\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: False
Daftar (listOfStrings) dapat berisi beberapa item (minimal 20) dan harus diperiksa terhadap ribuan string (seperti myString).
Apakah ada cara yang lebih baik (lebih efisien) untuk menulis kode ini?
sumber
ketika Anda membangun string Anda harus seperti ini
sumber
Ada sejumlah saran dari pertanyaan serupa sebelumnya " Cara terbaik untuk menguji string yang ada terhadap daftar besar yang sebanding ".
Regex mungkin cukup untuk kebutuhan Anda. Ekspresi akan menjadi gabungan dari semua substring kandidat, dengan
|
operator " " OR di antara mereka. Tentu saja, Anda harus berhati-hati terhadap karakter yang tidak terhindar ketika membangun ekspresi, atau kegagalan untuk mengkompilasinya karena kompleksitas atau keterbatasan ukuran.Cara lain untuk melakukan ini adalah dengan membangun struktur data trie untuk mewakili semua substring kandidat (ini mungkin agak menduplikasi apa yang dilakukan pencocokan regex). Saat Anda melangkah melalui setiap karakter dalam string tes, Anda akan membuat pointer baru ke akar trie, dan memajukan pointer yang ada ke anak yang sesuai (jika ada). Anda mendapatkan kecocokan saat pointer mana saja mencapai daun.
sumber
Saya menyukai jawaban Marc, tetapi membutuhkan Contains yang cocok untuk menjadi CaSe InSenSiTiVe.
Ini solusinya:
sumber
Berdasarkan pola Anda, satu peningkatan adalah mengubah menggunakan StartsWith alih-alih Berisi. Mulai Dengan hanya perlu beralih melalui setiap string sampai menemukan ketidakcocokan pertama daripada harus memulai kembali pencarian di setiap posisi karakter ketika menemukan satu.
Juga, berdasarkan pola Anda, sepertinya Anda mungkin dapat mengekstrak bagian pertama dari jalur untuk myString, lalu membalikkan perbandingan - mencari jalur awal myString dalam daftar string daripada sebaliknya.
EDIT : Ini akan lebih cepat menggunakan ide HashSet @Marc Gravell menyebutkan karena Anda dapat mengubah
Contains
keContainsKey
dan pencarian akan menjadi O (1), bukan O (N). Anda harus memastikan bahwa jalurnya sama persis. Perhatikan bahwa ini bukan solusi umum seperti @Marc Gravell tetapi dirancang untuk contoh Anda.Maaf untuk contoh C #. Saya belum punya cukup kopi untuk diterjemahkan ke VB.
sumber
Pertanyaan lama. Tapi karena
VB.NET
itu persyaratan aslinya. Menggunakan nilai yang sama dari jawaban yang diterima:sumber
Sudahkah Anda menguji kecepatannya?
yaitu, sudahkah Anda membuat set sampel data dan membuat profil? Mungkin tidak seburuk yang Anda pikirkan.
Ini juga bisa menjadi sesuatu yang bisa Anda buat menjadi utas terpisah dan memberikan ilusi kecepatan!
sumber
Jika kecepatan sangat penting, Anda mungkin ingin mencari algoritma Aho-Corasick untuk set pola.
Ini adalah trie dengan tautan kegagalan, yaitu kompleksitas adalah O (n + m + k), di mana n adalah panjang teks input, m panjang kumulatif pola, dan k jumlah kecocokan. Anda hanya perlu memodifikasi algoritme untuk diakhiri setelah kecocokan pertama ditemukan.
sumber
sumber
Kelemahan dari
Contains
metode ini adalah tidak memungkinkan untuk menentukan tipe perbandingan yang sering penting ketika membandingkan string. Itu selalu peka terhadap budaya dan peka terhadap huruf besar-kecil. Jadi saya pikir jawaban WhoIsRich sangat berharga, saya hanya ingin menunjukkan alternatif yang lebih sederhana:sumber