计算C#字符串中的重复字符

时间:2019-09-27 13:42:47

标签: c#

我是C#的新手,正在尝试弄清楚如何计算字符串中重复项的数量。输入和输出示例为:

"indivisibility" -> 1 # 'i' occurs six times
"Indivisibilities" -> 2 # 'i' occurs seven times and 's' occurs twice
"aA11" -> 2 # 'a' and '1'
"ABBA" -> 2 # 'A' and 'B' each occur twice

到目前为止,我的代码如下:

using System;
using System.Collections;
using System.Linq;

public class Kata
{
  public static int DuplicateCount(string str)
  {
    Stack checkedChars = new Stack();
    Stack dupChars = new Stack(); 

    str = str.ToLower();

    for (int i=1; i < str.Length; i++) {
      var alreadyCounted = checkedChars.Contains(str[i]) && dupChars.Contains(str[i]);

      if (!checkedChars.Contains(str[i])) {
         checkedChars.Push(str[i]);
      } else if (checkedChars.Contains(str[i])) {
         dupChars.Push(str[i]);
      } else if (alreadyCounted) {
        break;
      }
    }
    return dupChars.Count;
  }
}

我的方法是遍历字符串中的每个字符。如果以前没有看到过,请将其添加到“ checkedChars”堆栈中(以对其进行跟踪)。如果已经计算过,请将其添加到“ dupChars”堆栈中。但是,这使测试失败。例如:

aabbcde是字符串,并且测试失败并显示:Expected: 2 But Was: 1

此外,当我解决错误时,似乎checkedChars堆栈为空。

任何人都可以发现我出了错吗?

4 个答案:

答案 0 :(得分:2)

我建议您改用LINQ。这是解决问题的更合适的工具,它可以使代码更简洁:

class Program
{
     static void Main(string[] args)
     {
          var word = "indivisibility";
          Console.WriteLine($"{word} has {CountDuplicates(word)} duplicates.");
          word = "Indivisibilities";
          Console.WriteLine($"{word} has {CountDuplicates(word)} duplicates.");
          word = "aA11";
          Console.WriteLine($"{word} has {CountDuplicates(word)} duplicates.");
          word = "ABBA";
          Console.WriteLine($"{word} has {CountDuplicates(word)} duplicates.");

          Console.ReadLine();
     }
     public static int CountDuplicates(string str) =>
            (from c in str.ToLower()
             group c by c
             into grp
             where grp.Count() > 1
             select grp.Key).Count();
    }
}

以下是输出:

indivisibility has 1 duplicates.
Indivisibilities has 2 duplicates.
aA11 has 2 duplicates.
ABBA has 2 duplicates.

希望这会有所帮助。

答案 1 :(得分:1)

您需要从int i = 0开始循环,因为索引从0开始而不是1。因此,要获取第一个字符,您需要调用str[0]

您也可以删除break,因为您的代码将永远不会碰到它,因为前两个条件是完全相反的。相反,请先检查alreadyCounted是否为真,并使用continue(而不是break,因为它会完全退出循环!)跳到下一个迭代,以避免重复计数相同的字符

答案 2 :(得分:0)

您可以为此使用LINQ-

    var str = "aabbcde";
    var count = str.ToLower().GroupBy(x => x).Select(y => y).Where(z=>z.Count()>1).Count();

答案 3 :(得分:0)

您还可以使用MoreLinq.CountBy:

using System;
using System.Linq;
using MoreLinq;

namespace ConsoleApp1
{
    internal class Program
    {
        private static int CountDuplicateCharacters(string s)
        {
            return s?.CountBy(c => c).Where(kvp => kvp.Value > 1).Count() ?? 0;
        }

        private static void Main(string[] args)
        {
            foreach (var s in new string[] { "indivisibility", "Indivisibilities", "aA11", "ABBA" })
            {
                Console.WriteLine(s + ": " + CountDuplicateCharacters(s));
            }
        }
    }
}

如果您不想区分大小写,则需要提供EqualityComparer作为CountBy的第二个参数。