C# 你能用子字符串比较对字符串列表进行二进制搜索吗?

C# 你能用子字符串比较对字符串列表进行二进制搜索吗?,c#,C#,问题是我有一个大约800000个字符串元素的列表,并且试图匹配字符串的子字符串。好的,现在我通过一个彻底的搜索(蛮力),但这需要几个小时。我希望有一种更快更优雅的方法 namespace Sorting_Program_Ver1_1 { class Program { static void Main(string[] args) { string[] tempStringArray; string[] dataStringArray; string[] dotd

问题是我有一个大约800000个字符串元素的列表,并且试图匹配字符串的子字符串。好的,现在我通过一个彻底的搜索(蛮力),但这需要几个小时。我希望有一种更快更优雅的方法

namespace Sorting_Program_Ver1_1
{
class Program
{
    static void Main(string[] args)
    {
        string[] tempStringArray; string[] dataStringArray; string[] dotdotStringArray;
        List<string> myList = new List<string>();
        List<string> twoDots = new List<string>();
        Console.WriteLine("Starting program - initialising variables");

        tempStringArray = File.ReadAllLines("C:\\datadomains");
        int count = 0;

        for (int a = 0; a < tempStringArray.Length - 1; a++)
        {
            if (tempStringArray[a].Length > 0)
            {
                myList.Add(tempStringArray[a]);
            }
        }
        Console.WriteLine("Adding items to string list");

        for (int b = 0; b < myList.Count; b++)
        {
            for (int c = 0; c < myList[b].Length; c++)
            {
                if (myList[b][c] == '.')
                {
                    count++;
                }
            }
            if (count == 2)
            {
                twoDots.Add(myList[b]);
            }
            count = 0;
        }
        Console.WriteLine("Sorting the list into 2");

        dotdotStringArray = twoDots.ToArray();
        System.IO.File.WriteAllLines("C:\\twoDots.txt", dotdotStringArray);

        Console.WriteLine("Starting the search...");
        for (int d = 0; d < twoDots.Count; d++)
        {
            for (int e = myList.Count - 1; e > 0; e--)
            {
                if (myList[e] == "")
                {
                    Console.WriteLine("Removing empty space...");
                    myList.RemoveAt(e);              
                }

                int start = myList[e].Length - twoDots[d].Length;
                if (start >= 0)
                {
                    if (twoDots[d] == myList[e].Substring(start, twoDots[d].Length))
                    {
                        if (twoDots[d] != twoDots[d])
                        {
                            Console.WriteLine("Removing...", myList[e]);
                            myList.RemoveAt(e);
                        }
                    }                       
                }
            }
        }

        Console.WriteLine("Saving to file ...");
        dataStringArray = myList.ToArray();
        System.IO.File.WriteAllLines("C:\\myList.txt", dataStringArray);
        Console.WriteLine("Saved to file");
        Console.WriteLine("Exit program");
    }
}
我正在尝试查看列表,将字符串与子字符串匹配,并删除子域。
这更清楚吗?

这里不能选择二进制搜索,因为这意味着整个树本身是按一定顺序排列的(理想情况下是平衡的)。由于您希望进行部分比较,顺序不重要,因此二进制搜索没有帮助

您可能需要研究Boyer-Moore字符串搜索算法,该算法非常有效,特别是对于长字符串

请点击查看。如果你只是在Google上搜索“Boyer Moore”,你也应该能够找到一些有趣的链接,比如关于算法的书中的这一章:


还有一种叫做Breslauer Grossi Mignosi的最新算法(你可以在网站上找到)。我还没有研究过这个,所以我不能对此发表评论。

如果您对字符串的完全相等感兴趣,或者如果您正在寻找从正在搜索的字符串的开头开始的子字符串,则只能执行二进制搜索,而您不是,所以不,不能使用二进制搜索。

如果要查找字符串的任何部分作为子集,则要生成的是后缀Trie。实际上,没有有效负载,但是您可以构建一个包含整个文本所有已知后缀的Trie,这可以在对文本的单个O(n)遍历中完成。这比只在内存中存储一个大字符串要占用更多的内存,但它是存储与字符串相关的数据的一种非常有效的方法。然后,对子字符串的搜索是对trie的O(m)操作(其中m是您正在搜索的子字符串的长度),这将非常快

如果您只想匹配整个单词,还可以将所有单词放入一个
HashSet
,也许可以使用构造函数重载忽略大小写,然后对给定单词进行O(1)检查

后缀树(Trie变量将没有出现负载):


在所有计算中,效率/性能和内存是平衡点。您可以牺牲内存来换取性能,也可以牺牲性能来换取内存节约,但很难同时获得这两种性能:

时间?你的内存占用是多少?分页可能是个问题……我很难理解您的代码真正想要做什么。你能给出一些你正在搜索的字符串的例子,以及你正在搜索的子字符串的类型吗?有很多有效的方法,二进制搜索,字典,ABB等等。但是你的子字符串比较到底是什么意思呢?你的代码可以从各种方式的重构中受益。你能简单描述一下它应该做什么吗?你想用
if(twoDots[d]!=twoDots[d])
行做什么?为什么它不等于它本身呢?字符串列表不像一个有序的列表,所以二进制搜索可能不是一个选项。@Tigran如果这是唯一的问题,你总是可以对列表进行排序。这里的要点是,即使对列表进行了排序,也不可能做到这一点。@Hector210387-我给出的wikipedia链接显示了一个示例并概述了实现。用谷歌搜索一下,你会看到其他一些例子。
mylist[0]= ".bob.com"
mylist[1]= ".steve.bob.com"
mylist[2]= ".steve.job.bob.com"
...
mylist[800000]= ".coffee.com"

substring=".bob.com"