编写一个比较两个字符串并返回第三个字符串的函数,该字符串仅包含两个字母中出现的字母

时间:2010-01-15 10:10:03

标签: c# .net algorithm data-structures

我得到了这个功课。并以下列方式解决了它。我需要你的意见是否是一个好的方法,或者我需要使用任何其他数据结构来更好地解决它。

    public string ReturnCommon(string firstString, string scndString)
    {
        StringBuilder newStb = new StringBuilder();
        if (firstString != null && scndString != null)
        {
            foreach (char ichar in firstString)
            {
                if (!newStb.ToString().Contains(ichar) && scndString.Contains(ichar))
                    newStb.Append(ichar);
            }
        }
        return newStb.ToString();
    }

9 个答案:

答案 0 :(得分:19)

对于替代解决方案,您可以将字符串视为枚举,并使用Intersect(),如下所示:

    public static string Common(string first, string second)
    {
        return new string((first.Intersect(second)).ToArray());
    }

答案 1 :(得分:8)

对于第一种方法来说这很好,但是你可以做一些改进,并且有一个小错误。

  • 如果b包含a中已存在于c中的字符,则会重复该字符。
  • 为避免重复,您可以考虑使用Set来存储字符,因为Set不会重复。
  • 使用+=连接组装字符串通常效率低下;考虑使用StringBuilder或类似的字符串汇编类。
  • 您的变量名称不是很具描述性。
  • 如果ab为空,则您根本不需要做任何工作!只需返回一个空字符串。

通过想象如果开始使用大字符串,算法如何缩放,您也可以考虑一些更复杂的改进。例如,一种方法可能是如果一个字符串比另一个字符串长得多,您可以对较长的字符串进行排序并删除重复字符串。然后你可以很快地对较短字符串的字符进行二进制搜索。

答案 2 :(得分:3)

为了改进John Feminella的最后一个建议,比二分搜索(对于任何足够长的字符串)更快的是在hashset中查找;或者在256元素的布尔数组中查找,如果它们是ASCII或UTF8字符而不是UTF16字符。

  • 实例化一个空的hashset,或一个空的布尔数组;将此变量命名为found
  • 对于第一个字符串中的每个字符,要么将char添加到hashset(但要注意第一个字符串中的重复字符), 或者将found数组中的相应元素设置为true; 这将花费线性O(n)时间。
  • 对于第二个字符串中的每个字符,测试字符集中是否存在字符 或者'found'数组中的相应元素是否为真: 如果找到,则将该字符添加到返回字符串,并删除该字符 从hashset或清除数组中的boolean元素,以便它不会再次被找到(要小心第二个字符串中的重复字符);这将花费线性O(n)时间。

答案 3 :(得分:2)

似乎很好。您可以根据所使用的语言进行一对优化:

  • 你可以将b的字母收集到一些有序的结构中(以便更快地搜索它),如果它不重复......更好(一套)。
  • 您可以使用某种StrignBuilder(如果它是Java或.Net)来重新创建循环内每个连接的字符串

无论如何,这是对大型,大型字符串有用的优化......所以,我不知道它们是否适合您的使用,或者是否适用于预期的家庭作业。

答案 4 :(得分:2)

取决于输入字符串的多长时间字母是什么以及输出应该如何(重复)还有一些其他字符串方法

例如:

如果字母 只有[AZ]字符每个字母在输出字符串中只显示 可以构建单独的字符串(或字符表)'ABC ... XZ'(让我们称之为letters)并运行for each循环letters并检查两个来自letters的每个字母的输入字符串。

这个为每个输入字符串提供26次循环迭代不再然后 52次调用 Contains()方法 - 无论是什么输入字符串的长度。

答案 5 :(得分:1)

使用LINQ:

a.ToCharArray().Intersect<char>(b.ToCharArray())

然而,这是区分大小写的。

答案 6 :(得分:0)

仅供参考:这是C / C ++代码:

/* Q: Write a function f(a, b) which takes two character string arguments
      and returns a string containing only the characters found in both
      strings in the order of a. */

#include <iostream>
#include <string>
#include <cstring>
#include <map>
using namespace std;

/* A: Unclear: repeated chars in string a? */
string CommonChars(const char* a, const char* b)
{
    string result("");

    if (!a || !b || !*a || !*b)
        return result;

    map<char, bool> hash;
    int len1 = strlen(a), len2 = strlen(b);

    for (int i = 0; i < len2; ++i)
        hash[b[i]] = true;

    for (int i = 0; i < len1; ++i)
    {
        map<char, bool>::iterator it = hash.find(a[i]);
        if (it != hash.end() && it->second)
        {
            result += a[i];
            hash[a[i]] = false; // OR:  hash.erase(it);
        }
    }

    return result;
}

int main()
{
    cout << CommonChars("abcdefgbx", "gcfcba") << endl;

    return 0;
}
/* Output:
abcfg
 */

答案 7 :(得分:0)

这是我在python中的解决方案。如果我没有错,它应该采用线性O(n)时间。

# Write a function f(a, b) which takes two character string arguments
# and returns a string containing only the characters found in both
# strings in the order of a. 
first_string = "attempt" 
second_string="tmay" #second string
result = []

#it's O(n) operation
for char in first_string:
   if char in second_string:
      if char not in result:
         result.append(char)

print result

结果如下:

['a', 't', 'm']

答案 8 :(得分:-1)

对我来说看起来不错,但对于上帝的人来说 - 使用一些描述性的变量名称!!