Hier können Sie einen Golang-POC für die Berechnung der Abstände zwischen den angegebenen Wörtern haben. Sie können die minDistance
und difference
für andere Bereiche anpassen.
Spielplatz: https://play.golang.org/p/NtrBzLdC3rE
package main
import (
"errors"
"fmt"
"log"
"math"
"strings"
)
var data string = `DIE ROTE KUH SPRANG ÜBER DAS GRÜNE HUHN-DIE ROTE KUH SPRANG ÜBER DIE ROTE KUH-DER ROTE FUCHS SPRANG ÜBER DIE BRAUNE KUH`
const minDistance float64 = 2
const difference float64 = 1
type word struct {
data string
letters map[rune]int
}
type words struct {
words []word
}
// Print macht die Daten in Wort übersichtlich
func (w word) Print() {
var (
leng int
c int
i int
key rune
)
fmt.Printf("Daten: %s\n", w.data)
leng = len(w.letters) - 1
c = 0
for key, i = range w.letters {
fmt.Printf("%s:%d", string(key), i)
if c != leng {
fmt.Printf(" | ")
}
c++
}
fmt.Printf("\n")
}
func (ws words) fuzzySearch(data string) ([]word, error) {
var (
w word
err error
founds []word
)
w, err = initWord(data)
if err != nil {
log.Printf("Fehler: %s\n", err.Error())
return nil, err
}
// Alle Wörter durchlaufen
for i := range ws.words {
letters := ws.words[i].letters
//
var similar float64 = 0
// Durchlaufen der Buchstaben der Eingabedaten
for key := range w.letters {
if val, ok := letters[key]; ok {
if math.Abs(float64(val-w.letters[key])) <= minDistance {
similar += float64(val)
}
}
}
lenSimilarity := math.Abs(similar - float64(len(data)-strings.Count(data, " ")))
log.Printf("Vergleiche %s mit %s, ich habe %f ähnliche Buchstaben gefunden, mit Gewicht %f", data, ws.words[i].data, similar, lenSimilarity)
if lenSimilarity <= difference {
founds = append(founds, ws.words[i])
}
}
if len(founds) == 0 {
return nil, errors.New("keine Ähnlichkeiten gefunden für Daten: " + data)
}
return founds, nil
}
func initWords(data []string) []word {
var (
err error
words []word
word word
)
for i := range data {
word, err = initWord(data[i])
if err != nil {
log.Printf("Fehler im Index [%d] für Daten: %s", i, data[i])
} else {
words = append(words, word)
}
}
return words
}
func initWord(data string) (word, error) {
var word word
word.data = data
word.letters = make(map[rune]int)
for _, r := range data {
if r != 32 { // Leerzeichen nicht speichern
word.letters[r]++
}
}
return word, nil
}
func main() {
var ws words
words := initWords(strings.Split(data, "-"))
for i := range words {
words[i].Print()
}
ws.words = words
solution, _ := ws.fuzzySearch("DIE BRAUNE FUCHS SPRANG ÜBER DIE ROTE KUH")
fmt.Println("Mögliche Lösungen: ", solution)
}
3 Stimmen
Algorithmen, die typischerweise diese Art von Aufgaben erledigen, arbeiten daran festzustellen, wie viele Änderungen erforderlich sind, um eine untersuchte Zeichenfolge in die Zielzeichenfolge zu verwandeln. Diese Art von Algorithmen funktioniert überhaupt nicht gut in einer Situation wie dieser. Ich denke, es wird sehr schwierig sein, einen Computer dazu zu bringen, das hinzubekommen.
4 Stimmen
Levenshtein-Distanz-Quellcode in vielen Sprachen: Java, Ruby, Python, PHP, usw. en.wikibooks.org/wiki/Algorithm_Implementation/Strings/…
11 Stimmen
Im Allgemeinen hängt das, was als "nächster String" gilt, von dem verwendeten Ähnlichkeitsmaß und den Strafen ab, die für das Einführen von Lücken in der Ausrichtung verwendet werden. Zum Beispiel, betrachten Sie "Kuh" und "Huhn" als ähnlicher als "Kuh" und "rot" (weil sie verwandte Konzepte sind), oder ist es umgekehrt (weil "Huhn" mehr Buchstaben hat als "Kuh")? Aber bei einem Ähnlichkeitsmaß und Lückenstrafe kann gezeigt werden, dass der Levenshtein-Algorithmus unten garantiert den nächstgelegenen String findet. Dasselbe gilt für Needleman-Wunsch und Smith-Waterman (weiter unten).
0 Stimmen
Führen Sie eine Zeichen- oder Wortgruppierung durch. Bewerten Sie dies.