为了账号安全,请及时绑定邮箱和手机立即绑定

Java 8 使用 Streams 算法搜索 ArrayList 失败

Java 8 使用 Streams 算法搜索 ArrayList 失败

一只甜甜圈 2024-01-25 10:35:51
我们正在使用 Stream 来搜索字符串的 ArrayList 字典文件已排序并包含 307107 个小写单词我们正在使用 findFirst 从 TextArea 中的文本中查找匹配项只要单词拼写错误超出 3 个字符 搜索有有利的结果如果拼写错误的单词是这样的“Charriage”,则结果与匹配完全不相近明显的目标是在不需要查看大量单词的情况下获得尽可能接近正确的结果这是我们正在测试的文本Tak acheive it hommaker 和 aparent as Chariage NOT ME Charriag 添加缺失的元音到 Cjarroage我们对流搜索过滤器进行了一些重大更改,并进行了合理的改进我们将编辑发布的代码,以仅包含搜索失败的代码部分 在对流过滤器进行的代码更改之后在代码更改之前,如果searchString 在位置 1 处有一个拼写错误的字符 在字典中找不到结果 新的搜索过滤器修复了这个问题我们还通过增加endsWith 的字符数量添加了更多搜索信息所以仍然失败!如果 searchString(拼写错误的单词)在单词末尾缺少一个字符,并且该单词在位置 1 到 4 之间有一个不正确的字符,则搜索失败我们正在努力添加和删除字符,但我们不确定这是否可行解决方案如果您想要我们将在 GitHub 上发布的完整项目,请在评论中询问,我们将不胜感激。问题仍然是当拼写错误的单词中缺少多个字符时如何修复此搜索过滤器?经过几个小时的免费 txt 词典搜索后,这是最好的A 侧栏事实之一,它有 115726 个长度 > 5 的单词,并且单词末尾有一个元音。这意味着它有 252234 个末尾没有元音的单词这是否意味着我们有 32% 的机会通过在 searchString 的末尾添加元音来解决问题?不是一个问题,只是一个奇怪的事实!这里是字典下载的链接,并将words_alpha.txt文件放在C盘上的C:/A_WORDS/words_alpha.txt"); words_alpha.txt
查看完整描述

3 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

我正在添加 JavaFX 答案。这个应用程序使用Levenshtein Distance. 您必须单击Check Spelling才能开始。您可以从列表中选择一个单词来替换当前正在检查的单词。我注意到Levenshtein Distance返回了很多单词,因此您可能需要找到其他方法来进一步减少列表。

主要的

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);

    }

}

自定义Word类


/**

 *

 * @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 类


/**

 *

 * @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;

    }

}


查看完整回答
反对 回复 2024-01-25
?
梦里花落0921

TA贡献1772条经验 获得超5个赞

您只需要进一步了解词典即可
我们确定您从词典中得到了很多建议的单词?
我们测试了您的代码,有时它发现了 3000 个或更多可能的匹配项哇,
所以这是一个很大的改进。它仍然需要大量的测试,我们使用这条线进行测试,获得了 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


查看完整回答
反对 回复 2024-01-25
?
桃花长相依

TA贡献1860条经验 获得超8个赞

我认为你应该使用类似于Levenshtein Distanceor的东西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


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


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


查看完整回答
反对 回复 2024-01-25
  • 3 回答
  • 0 关注
  • 41 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信