İki dizeyi eşleştirin, ancak bir dereceye kadar hataya izin verin


10

İki dizeyi nasıl eşleştirebilirim, ancak aynı zamanda X karakterinin eşleşmede yanlış olmasına izin verir. Hata sayısı kontrol edilebilir bir değişken olmalıdır.

Dizede X karakter sayısı eşleşemezken, bir dizide kaç tane çalıştırılacağı konusunda bir sınır olmalıdır. İki dize verildiğinde, 5 karakterin farklı olmasına izin verebilirim, ancak art arda 2'den fazla olamaz.

Bu iki dizeyi karşılaştırmak için önerilen bir algoritma arıyorum, ya da belki zaten bunun için bilinen bir çözüm var.


4
Levenshtein mesafesi 'artık üst üste 2 den' özelliklerini, yani algoritmanın bir parçası olmasa da, bakmak için bir şey olabilir. Bkz ayrıca sayfanın vardır çok aradığınız şey olabilir ilgili diğer algoritmalar.

@MichaelT böyle bir şeyim olsaydı kesinlikle ihtiyaçlarımı karşılayacaktı. Teşekkürler.
Reactgular

@MichaelT Bunu buldum> dotnetperls.com/levenshtein Cevap olarak koymalısın, çünkü bu benim problemlerimi çözdü.
Reactgular

Soundex eşleşmesine bakmak isteyebilirsiniz. tr.wikipedia.org/wiki/Soundex
Gilbert Le Blanc

Yanıtlar:


12

Yaklaşık bir dize arama başlangıç ​​noktası Levenshtein mesafesidir . Bu algoritma, bir kelimeyi diğerine değiştirmek için tek karakterli düzenleme sayısını (ekleme, silme ve değiştirme) sayar.

Bunun bir örneği kitten-> sittingdüzenleme mesafesi üç olan

  1. k itten -> s itten ('k' yerine 's' yerine)
  2. sitt e n -> sitt i n ('e' yerine 'i' yerine)
  3. sittin -> sittin g (sonuna 'g' ekle)

Bu algoritmada, özellikle iki bitişik karakterin ('hte' - 'the' DL Mesafesi 1 ve Levenshtein mesafesinin 2 olması) için Damerau-Levenshtein mesafesi varyasyonları vardır ve bu nedenle genellikle yazım denetimi. Boşlukların önemli olduğu uygulamalar için diğer varyasyonlar vardır (DNA dizeleri).

Levenshtein mesafesi iyi bilinir ve bulmak çok zor değildir (bir zamanlar onun bir uygulamasını oracle'de bir işlev olarak avlamaya neden oldum - tüm verileri aşağı çekip sorgu kodu tarafını çalıştırmaktan çok daha hızlıydı). Rosettacode'un Levenshtein mesafesinin çok sayıda (54) uygulaması vardır (bazı dillerin bir yerde dize kütüphanesinin bir parçası olduğunu unutmayın - Java yapıyorsanız, apache commons lang'e bakın ). Wikibooks'un 31 uygulaması vardır ve ikisinde de üstünkörü bir bakışta aynı dil için aynı kod gösterilmez.

Bunun çalışma şekli, iki dize arasındaki ilişkiye karşılık gelen bir matris oluşturmaktır:

 .kitten
.0123456
s1123456
i2212345
t3321234
t4432123
i5543223
n6654332
g7765443

.Satır ve sütun size 'sadece' bir boş dize gelen her harfi ekleyerek hedef dizeye alabilirsiniz temsil eder. Bu ideal bir durum değildir, ancak algoritmayı tohumlamak için oradadır.

Değer o nokta ile aynıysa ('i' == 'i'), değer çapraz olarak sola doğru olan değerle aynıdır. İki nokta birbirine benzemiyorsa ('s'! = 'K') değer minimumdur:

  • yukarı ve sola çapraz + 1 (yerine koyma)
  • + 1'in hemen üstünde (ekleme)
  • doğrudan sola + 1 (silme)

Mesafeyi düzenle dönüş değeri, matrisin sağ alt tarafındaki değerdir.

Sağ alttan sol üste minimumla devam ederseniz, yapılan düzenlemeleri görebilirsiniz:

 .kitten
.0.   .
s.1   .
i  1  .
t   1 .
t    1.
i.....2
n      2
g......3

Bunun oldukça bellek yoğun bir yaklaşım olduğunu unutmayın. Tam matrisi oluşturmayarak bellek kapsamında azaltılabilir - tüm algoritmanın önem verdiği şey, verilerin bir alt kümesidir ve yalnızca bir önceki satırı (ve akımda hesaplananı) depolayarak uzaydan N*Muzaya azaltılabilir 2*max(N,M)kürek çekmek). Kod Projesi bunun nasıl yapılabileceğini gösterir (indirmek için C # kodu ile).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.