Χρησιμοποιώντας ένα δυαδικό Αναζήτηση δέντρο ως ορθογραφικού ελέγχου

ψήφοι
4

Αναρωτιέστε την πιο efficent τρόπος για να κάνει ένα δυαδικό δέντρο αναζήτησης σε ένα ορθογραφικό έλεγχο από την ανάγνωση στο παράδειγμα αρχείου λεξικό 1000 λέξεων και στη συνέχεια, έχοντας το ελέγξουμε άλλο έγγραφο που λένε έχει ένα ζευγάρι παραγράφους.

Δημοσιεύθηκε 05/12/2008 στις 03:05
πηγή χρήστη
Σε άλλες γλώσσες...                            


8 απαντήσεις

ψήφοι
8

ένα τριαδικό δέντρο trie θα ήταν πιο αποτελεσματικό

Απαντήθηκε 05/12/2008 στις 03:22
πηγή χρήστη

ψήφοι
0

Αν χρειαστεί να κάνετε μια αυτόματη προτείνουν αναζήτηση / πρόθεμα καθώς και, στη συνέχεια, ένα δέντρο Patricia ή radix δέντρο είναι αξίζει να εξετάσουμε.

Απαντήθηκε 05/12/2008 στις 03:26
πηγή χρήστη

ψήφοι
0

Με το παράδειγμα που έδωσε, οι επιδόσεις είναι πιθανό να είναι άνευ σημασίας, αφού σε υπολογιστή η όλη διαδικασία θα διαρκέσει περίπου 1% του χρόνου που χρειάζεται ο χρήστης να διαβάσει το πρώτο αποτέλεσμα που δείχνει, με την προϋπόθεση ότι δεν χρησιμοποιείτε μια εντελώς ηλίθια αλγόριθμο . Αλλά και πάλι, εγώ θα αναλάβει το πρόβλημα είναι αρκετά μεγάλη ότι η απόδοση είναι ένα θέμα.

Αν το αρχείο λεξικό presorted (όπως οι περισσότεροι είναι), και εάν το κείμενο είναι μικρό σε σχέση με το λεξικό, όπως περιγράφετε, τότε θα έμπαινε στον πειρασμό σοβαρά για να ταξινομήσετε το κείμενο, ίσως αφαίρεση διπλότυπων, και στη συνέχεια επαναλαμβάνεται σε δύο λίστες side-by -πλευρικής χρησιμοποιώντας την ίδια διαδικασία ως ένα είδος συγχώνευσης, εκτός από εσάς αναφέρετε αν κάθε λέξη το κείμενο περιλαμβάνεται στο λεξικό, αντί να εξάγει μια νέα λίστα.

Αυτό κάνει τη δουλειά σε περίπου Μ συγκρίσεις log M για το είδος, καθώς και το πολύ συγκρίσεις N + M για την επανάληψη, (πιθανώς λιγότερο, αλλά όχι την πολυπλοκότητα-κάτω). Αυτό είναι αρκετά κοντά στο βέλτιστο πολυπλοκότητα για μια λειτουργία one-off: για να απαλλαγούμε από το γραμμικό όρο στο Ν θα πρέπει να βρουν τρόπους για να μην διαβάσετε ολόκληρο το λεξικό από δίσκο σε όλα. Είμαι αρκετά σίγουρος ότι είναι δυνατό να bsearch στο αρχείο, δεδομένου μάλιστα ότι τα λόγια είναι αρκετά σύντομη, αλλά για τις μικρές Ν είναι εικασία αν επιδιώκει για τον τόπο θα είναι στην πραγματικότητα πιο γρήγορα από ό, τι σειριακά πρόσβαση στα δεδομένα.

Έχει τα ακόλουθα χαρακτηριστικά:

  • Δεν χρειάζεται να κρατάτε το λεξικό στη μνήμη, μόνο το κείμενο.
  • Παρ 'όλα αυτά, το μόνο που κάνει ένα πέρασμα πάνω από το αρχείο λεξικού.
  • Δεν κάνει καμία ακριβή επεξεργασία του λεξικού.

Φυσικά, εάν το αρχείο λεξικού δεν είναι προ-ταξινόμηση, τότε αυτό δεν λειτουργεί, και αν μπορείτε να κρατήσετε το λεξικό κρέμονται γύρω στη μνήμη για την επόμενη λειτουργία ορθογραφικού ελέγχου, στη συνέχεια, μπορείτε να αποσβέσει το κόστος των I / O και της επεξεργασίας του σε ένα δέντρο σε διάφορα διαφορετικά κείμενα, τα οποία θα είναι μια νίκη σε μακροπρόθεσμη βάση.

Αν το λεξικό είναι πραγματικά τεράστια, τότε ίσως να επωφεληθούν από την αποθήκευσή του στο δίσκο σε ένα προ-επεξεργασμένη μορφή που ισοδυναμεί με μια μη ισορροπημένη δέντρο σταθμίζονται σύμφωνα με τις σχετικές συχνότητες των διαφόρων λέξεων στη γλώσσα σας. Στη συνέχεια, μπορείτε να κάνετε λιγότερο από O (N) στο δίσκο για μικρά κείμενα, και στα περισσότερα λειτουργικά συστήματα δεν ενοχλεί την τροφοδοσία τους στη μνήμη καθόλου, απλά λειτουργία mmap το αρχείο και αφήστε το λειτουργικό σύστημα ανησυχείτε γι 'αυτό. Για ένα μεγάλο λεξικό, το σύνολο συστάδες που περιέχουν λέξεις που ξεκινούν με «διμεθυλο» δεν χρειάζεται να αγγίξει.

Ένα άλλο ζήτημα είναι ένα δέντρο άτεχνος για το λεξικό. Ένα δέντρο άτεχνος ίδια ανισορροπίες, όπως βλέπετε τα πράγματα σε αυτό, προκειμένου να καταστεί συχνά χρησιμοποιούμενες τιμές πιο γρήγορα να βρεθεί. Οι περισσότεροι κείμενο χρησιμοποιεί ένα μικρό αριθμό λέξεων κατ 'επανάληψη, οπότε αν το κείμενο είναι αρκετά μεγάλη ώστε να δικαιολογήσει την επιβάρυνση αυτή θα κερδίσει τελικά.

Και οι δύο παραπάνω υπόκεινται σε σημείο Steven A Lowe που για έγχορδα, ένα trie κερδίζει ένα κανονικό δέντρο. Δεν ξέρω αν θα βρείτε ένα άτεχνος trie off-the-shelf, όμως.

Απαντήθηκε 05/12/2008 στις 03:55
πηγή χρήστη

ψήφοι
1

Αν είστε απλώς προσπαθεί να δει αν υπάρχει μια συγκεκριμένη λέξη στο λεξικό σας (δηλαδή, είναι γραμμένες σωστά), τότε δεν νομίζω ότι ένα δυαδικό δένδρο αναζήτησης είναι ό, τι είστε μετά. Ένας καλύτερος τρόπος για να αποθηκεύσετε τις πληροφορίες θα είναι σε στυλ δέντρο όπου κάθε διαδοχικό κόμβο στο δέντρο σας είναι ένας χαρακτήρας, και διαβάζοντας τη διαδρομή μέχρι το τέλος του κόμβου σας δίνει την ορθογραφία της λέξης. Θα ήθελα επίσης να χρειαστεί να προσθέσετε ένα δείκτη για να δείξει μια λέξη-τέλος.

Για παράδειγμα: λένε λεξικό σας έχει αυτά τα λόγια: το αυτοκίνητο, καλάθι, γάτα, κύπελλο, κοπή

- C
  - A
    - R
      - end
      - T
    - T
      - end
  - U
    - P
      - end
    - T
      - end

Έλεγχος αν υπάρχει μια λέξη είναι ένα θέμα που αναζητούν σε κάθε γράμμα ξεχωριστά, και ότι υπάρχει στα παιδιά του τρέχοντος κόμβου.

Check for "cat"
Does "C" exist at the root level? Yes, move to the next letter.
Does "A" exist underneath C? Yes, move on.
Does "T" exist underneath A? Yes, move on.
Is there a word ending after the T? Yes. Word exists.

Check for "cu"
Does "C" exist at the root level? Yes, move to the next letter.
Does "U" exist at the root level? Yes, move to the next letter.
Is there a word ending after the U? No. Word does not exist.

Πώς να αποθηκεύσετε αυτές οι πληροφορίες είναι στο χέρι σας. Όπως Στίβεν τόνισε, ένα τριμερούς Αναζήτηση Trie θα μπορούσε να είναι ο τρόπος να πάει: κάθε κόμβος θα έχει 27 πιθανές κόμβους παιδί.

Απαντήθηκε 05/12/2008 στις 04:16
πηγή χρήστη

ψήφοι
3

Είσαι νεκρός-που για τη χρήση ενός δυαδικού δένδρου αναζήτησης; Ένα φίλτρο Bloom θα μπορούσε πιθανότατα να είναι μια πιο αποτελεσματική δομή δεδομένων.

Απαντήθηκε 05/12/2008 στις 04:34
πηγή χρήστη

ψήφοι
0

Βλέποντας ότι αυτό είναι ένα ερώτημα το σπίτι Πάω να υποθέσουμε ότι θα πρέπει να χρησιμοποιήσετε ένα απλό παλιό δυαδικό δέντρο (δεν Κόκκινο-Μαύρο δέντρα, AVL δέντρα, Radix δέντρα, κλπ). Η απάντηση λοιπόν είναι να προσπαθήσει να κρατήσει το δέντρο ισορροπημένη, όπως το φτιάξεις από τη λίστα λέξεων. Μία προσέγγιση είναι να τυχαίο τη λίστα πριν από την ανάγνωση μέσα, αυτό δίνει λογικά αποτελέσματα. Αλλά μπορείτε να πάρετε τα καλύτερα αποτελέσματα εάν παραγγείλετε την ακολουθία εισόδου (χρησιμοποιώντας την ίδια σύγκριση με αυτό που χρησιμοποιεί το δέντρο), στη συνέχεια, αναδρομικά διαιρεί την είσοδο επιστρέφει το μέσο μέχρι να μην υπάρχουν στοιχεία. Το αποτέλεσμα είναι ένα ισορροπημένο δέντρο.

Χτύπησα τρεις διαφορετικούς τρόπους για να γίνει αυτό σε C #:

private static IEnumerable<T> BinaryTreeOrder<T>(IList<T> range, int first, int last)
{
  if (first > last)
  {
    yield break;
  }

  int mid = (first + last) / 2;
  yield return range[mid];
  foreach (var item in BinaryTreeOrder(range, first, mid - 1))
  {
    yield return item;
  }
  foreach (var item in BinaryTreeOrder(range, mid + 1, last))
  {
    yield return item;
  }    
}

private static void BinaryTreeOrder<T>(IList<T> range, int first, int last, 
                                       ref IList<T> outList)
{
  if (first > last)
  {
    return;
  }

  int mid = (first + last) / 2;
  outList.Add(range[mid]);
  BinaryTreeOrder(range, first, mid - 1, ref outList);
  BinaryTreeOrder(range, mid + 1, last, ref outList);
}

private static void BinaryTreeOrder<T>(IList<T> range, int first, int last, 
                                       ref BinaryTree<T> tree) where T : IComparable<T>
{
  if (first > last)
  {
    return;
  }

  int mid = (first + last) / 2;
  tree.Add(range[mid]);
  BinaryTreeOrder(range, first, mid - 1, ref tree);
  BinaryTreeOrder(range, mid + 1, last, ref tree);
}
Απαντήθηκε 20/04/2011 στις 21:27
πηγή χρήστη

ψήφοι
1

Αυτό το site θα σας βοηθήσει να έχει την εφαρμογή σε Java.

Απαντήθηκε 12/06/2011 στις 04:07
πηγή χρήστη

ψήφοι
0

Όπως προτείνεται ένα trie θα ήταν πιο αποτελεσματικό από ένα δυαδικό δέντρο, αλλά μπορείτε να χρησιμοποιήσετε ένα HashMap και hash κάθε λέξη. Έχετε ένα μικρό λεξικό (1000 εγγραφές). Όπως μπορείτε να διασχίζουν το έγγραφό σας, ελέγξτε αν οι λέξεις είναι στο HashMap. Εάν δεν είστε η λέξη θεωρείται ότι είναι λανθασμένα.

Αυτό δεν θα σας δώσει πιθανή διόρθωση σε μια ανορθόγραφη λέξη. Αυτό ακριβώς σας λέει ναι ή όχι (σωστό ή όχι).

Αν θέλετε προτάσεις ορθογραφίας για λανθασμένες λέξεις, μπορείτε να ξεκινήσετε από τη λέξη στο αρχείο, στη συνέχεια, δημιουργούν όλες τις λέξεις 1 επεξεργαστείτε απόσταση και να προσθέσετε αυτά τα παιδιά της αρχικής λέξης. Με αυτό τον τρόπο θα έχετε την οικοδόμηση ενός γραφήματος. Πηγαίνετε 2 επίπεδα βαθιά για μέγιστη ταχύτητα vs ακρίβεια. Αν έχετε δημιουργήσει έναν κόμβο λέξη που περιλαμβάνεται στο λεξικό, μπορείτε να το προσθέσετε σε μια λίστα με τις πιθανές προτάσεις. Στο τέλος, επιστροφή στη λίστα των πιθανών προτάσεων.

Για την καλύτερη ορθογραφικό έλεγχο, δοκιμάστε να προσθέσετε στη φωνητική ταιριάζουν.

θάλασσα Yuh -> δείτε yah

Η μέθοδος αυτή (για τη δημιουργία γραφημάτων των χορδών 1 επεξεργαστείτε τα πόδια) είναι «αργή». Αλλά είναι μια καλή ακαδημαϊκή άσκηση. Runtime είναι O (n ^ κλαδιά).

Αν σας ενδιαφέρει εδώ είναι μια σύνδεση με ένα εγώ ο ίδιος κατασκευαστεί (για διασκέδαση): https://github.com/eamocanu/spellcheck.graph

Μερικά δείγματα γραφήματα: https://github.com/eamocanu/spellcheck.graph/tree/master/graph%20photos

Πρόσθεσα επίσης ένα συστατικό UI για να το οποίο παράγει τα γραφήματα. Αυτή είναι μια εξωτερική βιβλιοθήκη.

Απαντήθηκε 15/12/2011 στις 22:26
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more