Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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
C# 实现一种高效的求两个字符串相交的算法_C#_Algorithm - Fatal编程技术网

C# 实现一种高效的求两个字符串相交的算法

C# 实现一种高效的求两个字符串相交的算法,c#,algorithm,C#,Algorithm,实现一个算法,将两个字符串作为输入,并返回两个字符串的交集,每个字母最多表示一次 Algo:(考虑到使用的语言将是c#) 将两个字符串转换为字符数组 取较小的数组并为其生成一个哈希表,其中key为字符,值为0 现在循环遍历另一个数组,并增加哈希表中的计数(如果该字符存在) 现在取出值大于0的哈希表的所有字符 这些是交点值 这是一个O(n)解决方案,但它使用额外的空间、2个字符数组和一个哈希表 你们能想出比这更好的解决方案吗?你们不需要2个字符数组。String数据类型有一个内置的按位置索引器,该

实现一个算法,将两个字符串作为输入,并返回两个字符串的交集,每个字母最多表示一次

Algo:(考虑到使用的语言将是c#)

  • 将两个字符串转换为字符数组
  • 取较小的数组并为其生成一个哈希表,其中key为字符,值为0
  • 现在循环遍历另一个数组,并增加哈希表中的计数(如果该字符存在)
  • 现在取出值大于0的哈希表的所有字符
  • 这些是交点值
  • 这是一个O(n)解决方案,但它使用额外的空间、2个字符数组和一个哈希表


    你们能想出比这更好的解决方案吗?

    你们不需要2个字符数组。String数据类型有一个内置的按位置索引器,该索引器返回该位置的字符,因此您可以从0循环到(String.Length-1)。如果您对速度比优化存储空间更感兴趣,那么可以为其中一个字符串创建一个哈希集,然后创建第二个哈希集,该哈希集将包含最终结果。然后遍历第二个字符串,根据第一个哈希集测试每个字符,如果它存在,则将其添加到第二个哈希集。最后,您已经有了一个包含所有交叉点的散列集,省去了在散列表中查找非零值散列集的过程


    编辑:在所有关于根本不想使用任何内置容器的问题的评论都没有测试过这一点之前,我输入了这个,但我的想法是:

  • 对两个字符串进行适当的快速排序,这样就有了一个有序的字符序列
  • 将索引保留在两个字符串中,比较每个字符串中的“下一个”字符,选择并输出第一个,增加该字符串的索引
  • 继续,直到到达其中一个字符串的末尾,然后从其余字符串中提取唯一值
  • 不会使用额外的内存,只需要两个原始字符串、两个整数和一个输出字符串(或StringBuilder)。作为额外的奖励,输出值也将被排序

    第2部分: 这是我要写的(很抱歉评论,stackoverflow新手):

    私有静态字符串相交(字符串左、字符串右)
    {
    StringBuilder theResult=新建StringBuilder();
    string sortedLeft=Program.sort(左);
    string sortedRight=Program.sort(右);
    int leftIndex=0;
    int rightIndex=0;
    //使用“前最后一个字符”遍历字符串。
    if(sortedLeft[sortedLeft.Length-1]>sortedRight[sortedRight.Length-1])
    {
    字符串温度=sortedLeft;
    sortedLeft=sortedRight;
    SORTDRIGHT=温度;
    }
    char lastChar=默认值(char);
    while(leftIndex
    
    var s1 = "aabbccccddd";
    var s2 = "aabc";
    
    var ans = s1.Intersect(s2);
    

    我将这样做。它仍然是O(N),它不使用哈希表,而是使用长度为26的整数数组。(理想情况下)

  • 制作一个由26个整数组成的数组,每个元素代表alphebet.init到0的字母
  • 迭代第一个字符串,遇到字母时递减一个
  • 迭代第二个字符串,获取索引中与您遇到的任何字母对应的绝对值
  • 返回值大于0的所有索引对应的所有字母
  • 仍然是O(N),额外的空间只有26整数

    当然,如果不局限于小写或大写字符,则可能需要更改数组大小

    “每个字母最多代表一次”


    我假设这意味着您只需要知道交叉点,而不需要知道它们发生了多少次。如果是这样的话,那么您可以通过使用来缩减算法。您可以在此处生成交叉点,然后继续搜索其他匹配项,而不是存储计数并继续迭代第二个字符串第一个字符串的下一个可能匹配项。

    他已经提出了一个算法,并询问是否有人知道如何做得更好。嘿……看看上面我的算法,我需要知道我们是否可以在O(n)时间内解决这个问题,而不使用额外的空格。我不知道,所以我不知道,但这对集合(如Java或Python中的集合)来说不是很完美吗?一套也会有额外的空间。嘿,托马托桑威奇,这只是对社区的一种贡献,这样其他人就可以把它作为他/她的准备的参考。帮助他人是我的动机,我也在尽一切努力想出初步的解决方案,我不认为问问题有任何伤害,因为它既帮助了我,也帮助了其他人听起来不错。但我们可能仍然希望遍历哈希集以获取这些字符并将其转换为字符串。至少对于非常大的数据集,您可以做得比快速排序更好,因为您知道数据是字符。如果您处理的数据集非常大,您可以进行库排序,并获得O(n)性能,基本上是创建一个255个字符的数组。我没有“在两个字符串中保留一个索引,比较每个字符串中的“下一个”字符,选择并输出第一个字符,增加该字符串的索引。”你能说得更清楚一些吗?我的意思是这样的:char lastChar=default(char);而(leftIndex=sortedRight.Length)| |(sortedLeft[leftIndex]未知:“通过基本上创建255个字符数组…”AFAIK,C#字符串是UTF16,因此计数排序并不容易实现。对于字节大小的字符,bool[255](甚至8个整数)对于原始问题来说,这是一个有用的解决方案,开销最小。虽然这是一个简单的方法,但OP需要一个算法来直接解决。@Ahmad:如果你想要代码,只需使用Reflector来查看Intersect是如何实现的。@JP:true,th
    var s1 = "aabbccccddd";
    var s2 = "aabc";
    
    var ans = s1.Intersect(s2);