Java 8 Search ArrayList с ошибкой алгоритма Streams - PullRequest
0 голосов
/ 01 ноября 2019

Мы используем Stream для поиска в ArrayList строк, файл словаря отсортирован и содержит 307107 слов, все в нижнем регистре
Мы используем findFirst для поиска совпадений из текста в TextArea
AsДо тех пор, пока слово будет написано с ошибкой за пределами 3 символов, поиск будет иметь благоприятные результаты
Если слово с ошибкой похоже на этот "Charriage", то результаты не близки к совпадению
Очевидная цель состоит в том, чтобы приблизиться к правильному безнеобходимость взглянуть на огромное количество слов

Вот текст, который мы тестируем
Возьмите его, как создатель, и как видимый, как Chariage NOT ME Charriag добавьте недостающий гласный в Cjarroage

Мы внесли некоторые существенные изменения в фильтры поиска потока с разумными улучшениями
Мы отредактируем опубликованный код, включив в него ТОЛЬКО ту часть кода, где поиск не удался
И ниже, что изменения кода сделанык потоковым фильтрам
Перед изменением кода, если в searchString была ошибкаlled char в позиции 1 ничего не было найдено в словаре, новые поисковые фильтры исправили, что
Мы также добавили больше информации о поиске, увеличив количество символов для endSith
Так что все еще не работает! Если в searchString (слово с ошибкой) отсутствует символ в конце слова и если слово содержит неправильный символ в позициях с 1 по 4, поиск завершится неудачно
Мы работаем над добавлением и удалением символа, но не уверены в этомявляется работоспособным решением

Комментарии или код будут очень благодарны, если вы хотите завершить проект, который мы опубликуем на GitHub. Просто спросите в комментариях

Вопрос по-прежнему заключается в том, как исправить этот поисковый фильтр, если в слове с ошибкой пропущено несколько символов?

После нескольких часов поиска БЕСПЛАТНОГО словаря TXT это один из лучших
Факт в боковой панели: 115726 слов, длина которых> 5, и гласная в конце слова. Это означает, что в конце у него 252234 слова без гласной
Означает ли это, что у нас есть 32% шанс исправить проблему, добавив гласную в конец searchString? НЕ вопрос просто странный факт!

ЗДЕСЬ - ссылка на скачивание словаря и размещение файла words_alpha.txt на диске C в C: /A_WORDS/words_alpha.txt "); words_alpha.txt

Код до изменений

}if(found != true){

    lvListView.setStyle("-fx-font-size:18.0;-fx-background-color: white;-fx-font-weight:bold;");
    for(int indexSC = 0; indexSC < simpleArray.length;indexSC++){

    String NewSS = txtMonitor.getText().toLowerCase();

    if(NewSS.contains(" ")||(NewSS.matches("[%&/0-9]"))){
        String NOT = txtMonitor.getText().toLowerCase();
        txtTest.setText(NOT+" Not in Dictionary");
        txaML.appendText(NOT+" Not in Dictionary");
        onCheckSpelling();
        return;
    }

    int a = NewSS.length();
    int Z;
    if(a == 0){// manage CR test with two CR's
        Z = 0;
    }else if(a == 3){
        Z = 3;
    }else if(a > 3 && a < 5){
        Z = 4;
    }else if(a >= 5 && a < 8){
        Z = 4;
    }else{
        Z = 5;
    }

    System.out.println("!!!! NewSS "+NewSS+" a "+a+" ZZ "+Z);

    if(Z == 0){// Manage CR in TextArea
        noClose = true;
        strSF = "AA";
        String NOT = txtMonitor.getText().toLowerCase();
        //txtTo.setText("Word NOT in Dictionary");// DO NO SEARCH
        //txtTest.setText("Word NOT in Dictionaary");
        txtTest.setText("Just a Space");
        onCheckSpelling();   
    }else{
        txtTest.setText("");
        txaML.clear();
        txtTest.setText("Word NOT in Dictionaary");
        txaML.appendText("Word NOT in Dictionaary");
        String strS = searchString.substring(0,Z).toLowerCase();
        strSF = strS; 
    }
    // array & list use in stream to add results to ComboBox
    List<String> cs = Arrays.asList(simpleArray);
    ArrayList<String> list = new ArrayList<>();

    cs.stream().filter(s -> s.startsWith(strSF))
      //.forEach(System.out::println); 
    .forEach(list :: add);   

    for(int X = 0; X < list.size();X++){
    String A = (String) list.get(X);  

Улучшенный новый код

        }if(found != true){

    for(int indexSC = 0; indexSC < simpleArray.length;indexSC++){

    String NewSS = txtMonitor.getText().toLowerCase();
    if(NewSS.contains(" ")||(NewSS.matches("[%&/0-9]"))){
        String NOT = txtMonitor.getText().toLowerCase();
        txtTest.setText(NOT+" Not in Dictionary");

        onCheckSpelling();
        return;
    }
    int a = NewSS.length();
    int Z;
    if(a == 0){// manage CR test with two CR's
        Z = 0;
    }else if(a == 3){
        Z = 3;
    }else if(a > 3 && a < 5){
        Z = 4;
    }else if(a >= 5 && a < 8){
        Z = 4;
    }else{
        Z = 5;
    }

    if(Z == 0){// Manage CR
        noClose = true;
        strSF = "AA";
        String NOT = txtMonitor.getText().toLowerCase();
        txtTest.setText("Just a Space");
        onCheckSpelling();

    }else{
        txtTest.setText("");
        txtTest.setText("Word NOT in Dictionaary");
        String strS = searchString.substring(0,Z).toLowerCase();
        strSF = strS; 
    }
    ArrayList list = new ArrayList<>(); 
    List<String> cs = Arrays.asList(simpleArray);
    // array list & list used in stream foreach filter results added to ComboBox
    // Code below provides variables for refined search
    int W = txtMonitor.getText().length();

    String nF = txtMonitor.getText().substring(0, 1).toLowerCase();

    String nE = txtMonitor.getText().substring(W - 2, W);
    if(W > 7){
    nM = txtMonitor.getText().substring(W-5, W);
    System.out.println("%%%%%%%% nE "+nE+" nF "+nF+" nM = "+nM);
    }else{
    nM = txtMonitor.getText().substring(W-1, W);   
    System.out.println("%%%%%%%% nE "+nE+" nF "+nF+" nM = "+nM);
    }

    cs.stream().filter(s -> s.startsWith(strSF)
            || s.startsWith(nF, 0)
            && s.length()<= W+2
            && s.endsWith(nE)
            && s.startsWith(nF)
            && s.contains(nM)) 
    .forEach(list :: add);

    for(int X = 0; X < list.size();X++){
    String A = (String) list.get(X);
    sort(list);

    cboSelect.setStyle("-fx-font-weight:bold;-fx-font-size:18.0;");
    cboSelect.getItems().add(A);
    }// Add search results to cboSelect
    break;

Вотснимок экрана файла FXML, элементы управления названы так же, как имена, используемые в нашем коде, за исключением ComboBox
FXML layout

Ответы [ 3 ]

3 голосов
/ 02 ноября 2019

Я добавляю ответ JavaFX. Это приложение использует Levenshtein Distance. Вы должны нажать на Check Spelling, чтобы начать. Вы можете выбрать слово из списка, чтобы заменить текущее проверяемое слово. Я заметил, что Levenshtein Distance возвращает много слов, так что вы можете найти другие способы уменьшить список еще больше.

Main

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class App extends Application
{

    public static void main(String[] args)
    {
        launch(args);
    }

    TextArea taWords = new TextArea("Tak Carrage thiss on hoemaker answe");
    TextField tfCurrentWordBeingChecked = new TextField();
    //TextField tfMisspelledWord = new TextField();
    ListView<String> lvReplacementWords = new ListView();
    TextField tfReplacementWord = new TextField();

    Button btnCheckSpelling = new Button("Check Spelling");
    Button btnReplaceWord = new Button("Replace Word");

    List<String> wordList = new ArrayList();
    List<String> returnList = new ArrayList();
    HandleLevenshteinDistance handleLevenshteinDistance = new HandleLevenshteinDistance();
    ObservableList<String> listViewData = FXCollections.observableArrayList();

    @Override
    public void start(Stage primaryStage)
    {
        setupListView();
        handleBtnCheckSpelling();
        handleBtnReplaceWord();

        VBox root = new VBox(taWords, tfCurrentWordBeingChecked, lvReplacementWords, tfReplacementWord, btnCheckSpelling, btnReplaceWord);
        root.setSpacing(5);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public void handleBtnCheckSpelling()
    {
        btnCheckSpelling.setOnAction(actionEvent -> {
            if (btnCheckSpelling.getText().equals("Check Spelling")) {
                wordList = new ArrayList(Arrays.asList(taWords.getText().split(" ")));
                returnList = new ArrayList(Arrays.asList(taWords.getText().split(" ")));
                loadWord();
                btnCheckSpelling.setText("Check Next Word");
            }
            else if (btnCheckSpelling.getText().equals("Check Next Word")) {
                loadWord();
            }
        });
    }

    public void handleBtnReplaceWord()
    {
        btnReplaceWord.setOnAction(actionEvent -> {
            int indexOfWordToReplace = returnList.indexOf(tfCurrentWordBeingChecked.getText());
            returnList.set(indexOfWordToReplace, tfReplacementWord.getText());
            taWords.setText(String.join(" ", returnList));
            btnCheckSpelling.fire();
        });
    }

    public void setupListView()
    {
        lvReplacementWords.setItems(listViewData);
        lvReplacementWords.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
            tfReplacementWord.setText(newSelection);
        });
    }

    private void loadWord()
    {
        if (wordList.size() > 0) {
            tfCurrentWordBeingChecked.setText(wordList.get(0));
            wordList.remove(0);
            showPotentialCorrectSpellings();
        }
    }

    private void showPotentialCorrectSpellings()
    {
        List<String> potentialCorrentSpellings = handleLevenshteinDistance.getPotentialCorretSpellings(tfCurrentWordBeingChecked.getText().trim());
        listViewData.setAll(potentialCorrentSpellings);
    }
}

CustomWord Class

/**
 *
 * @author blj0011
 */
public class CustomWord
{

    private int distance;
    private String word;

    public CustomWord(int distance, String word)
    {
        this.distance = distance;
        this.word = word;
    }

    public String getWord()
    {
        return word;
    }

    public void setWord(String word)
    {
        this.word = word;
    }

    public int getDistance()
    {
        return distance;
    }

    public void setDistance(int distance)
    {
        this.distance = distance;
    }

    @Override
    public String toString()
    {
        return "CustomWord{" + "distance=" + distance + ", word=" + word + '}';
    }
}

HandleLevenshteinDistance Class

/**
 *
 * @author blj0011
 */
public class HandleLevenshteinDistance
{

    private List<String> dictionary = new ArrayList<>();

    public HandleLevenshteinDistance()
    {
        try {
            //Load DictionaryFrom file
            //See if the dictionary file exists. If it don't download it from Github.
            File file = new File("alpha.txt");
            if (!file.exists()) {
                FileUtils.copyURLToFile(
                        new URL("https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt"),
                        new File("alpha.txt"),
                        5000,
                        5000);
            }

            //Load file content to a List of Strings
            dictionary = FileUtils.readLines(file, Charset.forName("UTF8"));
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    public List<String> getPotentialCorretSpellings(String misspelledWord)
    {
        LevenshteinDistance levenshteinDistance = new LevenshteinDistance();
        List<CustomWord> customWords = new ArrayList();

        dictionary.stream().forEach((wordInDictionary) -> {
            int distance = levenshteinDistance.apply(misspelledWord, wordInDictionary);
            if (distance <= 2) {
                customWords.add(new CustomWord(distance, wordInDictionary));
            }
        });

        Collections.sort(customWords, (CustomWord o1, CustomWord o2) -> o1.getDistance() - o2.getDistance());

        List<String> returnList = new ArrayList();
        customWords.forEach((item) -> {
            System.out.println(item.getDistance() + " - " + item.getWord());
            returnList.add(item.getWord());
        });

        return returnList;
    }
}
2 голосов
/ 06 ноября 2019

Вам просто нужно было немного углубиться в словарь
Мы уверены, что вы получили много слов из словаря?
Мы проверяли ваш код, и иногда он находил 3000 или более возможных совпадений WOW
Итак, это БОЛЬШОЕ улучшение. Это все еще требует много испытаний, мы использовали эту линию для наших тестов со 100% благоприятными результатами.

Tske Charriage для hommaker и hommake в качестве hommaer

Нашистрах в том, что если спеллер действительно вырубает слово, это улучшение может решить эту степень орфографии
Мы уверены, что вы знаете, что если первая буква неверна, это не сработает
Как зенофоб для ксенофоба

Вот БОЛЬШОЕ улучшение тада

     cs.stream().filter(s -> s.startsWith(strSF)
            || s.startsWith(nF, 0)
            && s.length() > 1 && s.length() <= W+3 // <== HERE
            && s.endsWith(nE)
            && s.startsWith(nF)
            && s.contains(nM)) 
    .forEach(list :: add); 

Вы можете выслать чек на мой адрес 55 48 196 195

0 голосов
/ 01 ноября 2019

Этот вопрос является возможным дубликатом: Поисковое предложение в строках

Я думаю, вы должны использовать что-то похожее на Levenshtein Distance или Jaro Winkler Distance. Если вы можете использовать Apache's Commons. Я бы предложил использовать Apache Commons Lang. Он имеет реализацию Levenshtein Distance. Пример демонстрирует эту реализацию. Если вы установите расстояние (distance <= 2), вы можете получить больше результатов.

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

/**
 *
 * @author blj0011
 */
public class Main
{

    public static void main(String[] args)
    {
        try {
            System.out.println("Hello World!");
            File file = new File("alpha.txt");
            if (!file.exists()) {
                FileUtils.copyURLToFile(
                        new URL("https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt"),
                        new File("alpha.txt"),
                        5000,
                        5000);
            }

            List<String> lines = FileUtils.readLines(file, Charset.forName("UTF8"));
            //lines.forEach(System.out::println);

            lines.stream().forEach(line -> {
                int distance = StringUtils.getLevenshteinDistance(line, "zorilta");
                //System.out.println(line + ": " + distance);
                if (distance <= 1) {
                    System.out.println("Did you mean: " + line);
                }
            });

        }
        catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Выходное расстояние <= 1 </p>

Building JavaTestingGround 1.0
------------------------------------------------------------------------

--- exec-maven-plugin:1.5.0:exec (default-cli) @ JavaTestingGround ---
Hello World!
Did you mean: zorilla
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 1.329 s
Finished at: 2019-11-01T11:02:48-05:00
Final Memory: 7M/30M

Расстояние<= 2 </p>

Hello World!
Did you mean: corita
Did you mean: gorilla
Did you mean: zoril
Did you mean: zorilla
Did you mean: zorillas
Did you mean: zorille
Did you mean: zorillo
Did you mean: zorils
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 1.501 s
Finished at: 2019-11-01T14:03:33-05:00
Final Memory: 7M/34M

См. Возможный дубликат для получения дополнительной информации о Levenshtein Distance.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...