Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在arraylist中查找字符串的松散匹配项_Java_Algorithm_Substring - Fatal编程技术网

Java 在arraylist中查找字符串的松散匹配项

Java 在arraylist中查找字符串的松散匹配项,java,algorithm,substring,Java,Algorithm,Substring,我有一个巨大的数组列表,其中包含1000个条目,其中一个条目是“world”。而且,我有一个词“大世界”。我想让arraylist中的单词“大世界”与“世界”匹配 最具成本效益的方法是什么?我不能使用数组列表的.contains方法,如果我遍历所有1000个条目并按模式匹配它们,就性能而言,这将是非常昂贵的。我使用Java来实现这一点 你能告诉我最好的方法是什么吗 干杯, J假设您不知道arraylist元素的内容。您必须遍历整个arraylist 遍历arraylist将花费O(n) 排序ar

我有一个巨大的数组列表,其中包含1000个条目,其中一个条目是“world”。而且,我有一个词“大世界”。我想让arraylist中的单词“大世界”与“世界”匹配

最具成本效益的方法是什么?我不能使用数组列表的.contains方法,如果我遍历所有1000个条目并按模式匹配它们,就性能而言,这将是非常昂贵的。我使用Java来实现这一点

你能告诉我最好的方法是什么吗

干杯,
J

假设您不知道arraylist元素的内容。您必须遍历整个arraylist

遍历arraylist将花费O(n)


排序arraylist对您没有帮助,因为您谈论的是在一组字符串中搜索字符串。而且分类的费用也会更高。O(nlogn)

如果必须重复搜索列表,则可以使用的
sort()
binarySearch()
方法

附录:@user177883指出,O(logn)排序的成本必须与后续O(logn)搜索的收益进行权衡

“心”一词与[耳]一词相匹配


由于精确匹配是不够的,这种方法是不够的。

您可以将
ArrayList
中的每个元素拆分为单词,并在找到其中一个后立即停止

我想根据您在Java中开发的概要文件,使用Lucene您可以轻松地完成类似的工作

public class NodesAnalyzer extends Analyzer {   
    public TokenStream tokenStream(String fieldName, Reader reader) {

        Tokenizer tokenizer = new StandardTokenizer(reader)
        TokenFilter lowerCaseFilter = new LowerCaseFilter(tokenizer)
        TokenFilter stopFilter = new StopFilter(lowerCaseFilter, Data.stopWords.collect{ it.text } as String[])
        SnowballFilter snowballFilter = new SnowballFilter(stopFilter, new org.tartarus.snowball.ext.ItalianStemmer())

        return snowballFilter
    }   
}

    Analyzer analyzer = new NodesAnalyzer()

    TokenStream ts = analyzer.tokenStream(null, new StringReader(str)); 
    Token token = ts.next()

    while (token != null) {
       String cur = token.term()
       token = ts.next();
    }

注意:这是我从个人项目复制的Groovy代码,因此您必须将
Data.stopWords.collect{it.text}转换为String[]
以用于纯Java

我遇到了一个非常类似的问题

使用此
if
/
else if
语句解决了此问题

if (myArrayList.contains(wordThatIsEntered) 
    && wordThatCantBeMatched.equals(wordThatIsEntered)) {

    Toast.makeText(getApplicationContext(), 
    "WORD CAN'T BE THE SAME OR THAT WORD ISN'T HERE", 
    Toast.LENGTH_SHORT).show(); 
} 

else if (myArrayList.contains(wordThatIsEntered)) {

    Toast.makeText(getApplicationContext(), 
    "FOUND THE EXACT WORD YOU ARE LOOKING FOR!", 
    Toast.LENGTH_SHORT).show(); 
}

定义“松散”匹配。一个字符串必须是另一个字符串的子字符串吗?“心”和“耳”会匹配吗?这些是英语单词/短语吗?如果我们要求你摆脱ArrayList,你能吗?是的,你的权利!“心”这个词和“耳朵”匹配。我可以灵活地使用任何类型的数据结构!进一步澄清:1000个字符串的集合是静态的吗?您希望如何精确地进行子字符串匹配?给定一个单词U,你想在arraylist中找到一个单词V,这样V就是U的一个子串?如果U是其他V'的子字符串,这也是匹配吗?排序比搜索更昂贵。我可以这样做,但如果您看到二进制搜索是为了返回精确匹配而编写的。虽然我可能会编写一个定制的比较器,但识别松散匹配可能很困难。如何知道用户在找到值时是否要停止。用户希望查找字符串的所有出现的内容。然后,您将不得不使用许多二进制搜索。每次您发现一个事件时,您都会将其从adt中删除,然后执行另一个二进制搜索,最坏的情况是您可能会执行n个二进制搜索。最糟糕的情况是2nlogn。与顺序搜索相比,这是非常有效的。廉价的二进制搜索将使检查候选字符串中的每个单词以获得精确匹配成为可能。正如@Moron所指出的,澄清你的匹配标准可能会很有用。Lucene非常适合这样做,尤其是当它超过1000个单词时。