【问题标题】:Compare char in List C#比较列表 C# 中的字符
【发布时间】:2023-04-04 22:31:01
【问题描述】:

我想知道是否有任何 c# 函数可以检查字母是否存在不止一次?换句话说,我将一个字符串作为参数发送给一个函数,以检查一个字母是否存在不止一次。例如,字符串“AABDCK”应该返回“A”。有什么方法可以使用字典吗?

【问题讨论】:

  • AABB 的结果应该是什么
  • @M.kazemAkhgary ex: Assert.Equals('A', pg.GetCommonChar("AABCNMHM"));所以在这个例子中它应该返回 A 等等。
  • 用 LINQ 可以很容易地解决,请看我的答案。
  • 虽然 Linq 可能是当今解决此问题的最常用方法,但 OP 询问是否使用字典而不是 Linq 来解决它。因此,这个问题不是“C# LINQ find duplicates in List”的重复。

标签: c# list dictionary


【解决方案1】:

有什么方法可以使用字典吗??

是的,遍历字符串中的每个字符并跟踪Dictionary<char, int> 中每个字符的出现次数。

Dictionary<char, int> counts = new Dictionary<char, int>();
foreach (var ch in myString)
{
    if (counts.ContainsKey(ch))
    {
        counts[ch]++;
    }
    else counts.Add(ch, 1);
} 

检查字典中值大于 1 的键。

您也可以使用 Linq 执行此操作。我不在编译器面前,但它看起来像

List<char> multipleTimes = myString
    .GroupBy(c => c)
    .Select(g => new { Character = g.Key, Count = g.Count() })
    .Where(a => a.Count > 1)
    .Select(a => a.Character)
    .ToList();

【讨论】:

  • 投反对票的人可能不理解问题或者他不喜欢你;)
  • @EricJ。谢谢,我不明白为什么这家伙投了反对票……!
  • 也许投反对票的原因是,结果不符合要求的输出格式?只是猜测,我不会按设计投票,除非它是非常糟糕的答案,而且这个答案似乎并不坏......
【解决方案2】:

您可以使用 linq 来完成,查看下面的 cmets 以了解代码,例如:

public string GetLetterWithMoreOccurrences(string text)
{
   // check if the text was provided
   if (string.IsNullOrEmpty(letter))
      throw new ArgumentException("You must provide a text.", "text");

   // if it is lower than 2 chars, return the first one
   // I'm not sure if it is what you want, but let's consider it.
   if (text.Length <= 2)
      return text[0];

   // find the first letter
   var letter = text.GroupBy(c => c) // group by char
                    .Select(x => { Letter = x.Key, Total = x.Count() }) // in the group, count how many occurrences each letter has
                    .OrderByDescending(x => x.Total) // order by the total by descending
                    .First(); // get the first one

  return letter;
}

你可以检查一下:

var letter = GetLetterWithMoreOccurrences("AABDCK"); 
// should return "A"

现在,如果您想要所有出现多次的字母,您可以尝试:

public string GetLetterAllDuplicates(string text)
{
   // check if the text was provided
   if (string.IsNullOrEmpty(letter))
      throw new ArgumentException("You must provide a text.", "text");

   // if it is lower than 2 chars, return the first one
   // I'm not sure if it is what you want, but let's consider it.
   if (text.Length <= 2)
      return text[0];

   // find the first letter
   var letters = text.GroupBy(c => c) // group by char
                     // in the group, count how many occurrences each letter has
                     .Select(x => { Letter = x.Key, Total = x.Count() }) 
                      // get only the occurrences that has more than 1.. (you can change this parameter)
                     .Where(x => Total > 1) 
                     // get it as array
                     .ToArray();

  var result = string.Join(letters, "");

  return result ;
}

并使用它:

var text = GetLetterAllDuplicates("AABKCBD");
// should return "AB"

【讨论】:

  • 谢谢老兄 :) 很好的实现,
【解决方案3】:

你可以使用:

String.IndexOf("A");

它将返回第一个 A 出现的索引。 如果它返回 -1,则没有“A”事件。

这是我不使用 IndexOf 的 LINQ 实现:

string x = "AABCDEF";
List<char> repeatedCharacters = new List<char>();
var groupsOfChars = x.GroupBy(stringCharacter => stringCharacter);
groupsOfChars
.ToList()
.ForEach(item => {
    if (item.Count() > 1) repeatedCharacters.Add(item.Key);
});

或者如果您不需要该组:

string x = "AABCDEF";
List<char> repeatedCharacters = new List<char>();
x.GroupBy(stringCharacter => stringCharacter)
.ToList()
.ForEach(item => {
    if (item.Count() > 1) repeatedCharacters.Add(item.Key);
});

然后你可以检查一下:

repeatedCharacters.ForEach(item => {
    Console.WriteLine(item.ToString());
});
//Since repeatedCharacters is an array, you can just simply do:
string stringOfRepeatedCharacters = repeatedCharacters.ToString();
//So you can easily convert the values to a String.
//[ 'A', 'B' ] is the result and it can be "AB".

【讨论】:

  • 他正在寻找不止一次出现的字符。
  • IndexOf 会做到这一点,然后你可以搜索不是从零开始,而是最后一个“A”出现的最后一个位置。
  • 可以,但是多次扫描字符串效率不高。
  • 您的假设是他正在寻找多次出现的“A”。我的理解(可能是错误的)是他正在寻找多次出现的任何字符。如果我的理解是正确的,您必须多次扫描字符串,每个不同的字符一次。如果您对问题的理解是正确的,那么您是对的,只有一次扫描。
  • @darkndream 很努力,每个人都想回答是件好事,有点像裸露的皮肤:)。在这里我只想指出,结果不符合请求,但主要问题是如果 LINQ 可以链接操作,则它是最好的。如果将数据尽可能转换为可以强制枚举的内容,则可以获得最佳结果。例如聚合。所以这里最好的选择是将分组字符转换为字符并聚合为字符串。
【解决方案4】:

似乎将更多的木材带入森林,但似乎有些答案不完整,或者不完全符合要求,或者非常复杂:)。

        string input = "AABZFFZDCZZK";

        //can handle null and empty string...
        var rslt =
        (string.IsNullOrEmpty(input) ? string.Empty : input)
        .GroupBy(c => c)
        .Select(gc => gc.Count() > 1 ? gc.Key : (char)0)
        .Where(c => c != (char)0)
        .OrderBy(c => c)//optional
        .Aggregate(string.Empty, (c, n) => c + n)
        ;

结果是:

        "AFZ"

问题是为返回字符串提供多次出现的字符。

【讨论】:

    猜你喜欢
    • 2016-01-31
    • 2019-03-14
    • 2023-04-06
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 2020-12-18
    • 2014-05-09
    • 1970-01-01
    相关资源
    最近更新 更多