C# 检查字符串是否包含列表中的所有字符,并考虑重复项

本文关键字:字符 是否 字符串 检查 包含 列表 | 更新日期: 2023-09-27 18:34:03

如何检查字符串是否可以由字符列表(或数组(中的字符组成,同时考虑重复的字母。

所以,假设我有字符串(或字符数组/列表/

任何("abcc"和字符列表(或数组/字符串/任何东西,它都可以转换为任何("['c'],['b'],['a']"。如何相互检查这两个值,但也要考虑到"c"在 char 数组中只存在一次,因此它应该失败。

我知道我可以很容易地用任何一个".包含"并运行整个字符数组,在我去的时候从数组中删除该特定字符,或者使用"IndexOf"并做同样的事情,但我想知道是否有任何方法可以不从 char 数组中删除任何项目。

C# 检查字符串是否包含列表中的所有字符,并考虑重复项

var input = "abbc";
var validChars = new List<char>() { 'c', 'b', 'a' };
var invalidChars = validChars.Where(validChar => input.Count(inputChar => inputChar == validChar) > 1);

然后,您可以检查invalidChars是否有任何条目。

编辑:我会留下我的原始回复,但根据您的反馈,我认为这是正确的程序。

首先,我认为最好将字符数组转换为某种字典,以char作为键,int作为值(告诉您有多少个可用的字母(。

var charPool = new Dictionary<char, int>()
{
   { 'a', 2 },
   { 'b', 5 },
   { 'c', 5 },
   { 'd', 5 },
   { 'f', 0 },
   ...
   { 'z', 5 }
};

从那里,您可以获取输入字符串并应用一些 LINQ 来根据条件筛选值。我选择了!charPool.ContainsKey(inputChar)charPool[inputChar] < inputWord.Count(c => c == inputChar)作为我的匹配标准。这些基本上声明"对于应用此过滤器的每个字符,如果 1.字典中不存在该键,或 2.字典中该字符的值或编号小于输入字符串中该字符的出现次数,则该字符无效。

给定输入字符串

var inputWord = "bananafone";

下面的代码应该返回一个 IEnumerable 的字母 afea ,因为我们需要 3 个,只有 2 个; f,因为我们的条目在 0 处,我们需要 1;和e,因为该字母不存在条目。此外,还使用了.Distinct(),因为如果没有它,对于此示例,a将在遍历输入字符串并应用过滤器时输入 3 次。

var charsNeeded = inputWord.Where(inputChar => !charPool.ContainsKey(inputChar) || charPool[inputChar] < inputWord.Count(c => c == inputChar)).Distinct();

请注意,这种方法的一个缺点是,我们不计算我们拥有的字符数和需要的字符数之间的差异。但是,我认为实施起来并不困难;例如,您可以轻松地为输入字符串创建另一个字典,然后比较两者。

如果您正在处理大型字符列表,并且它们都是 ASCII 字符,那么为了保持高效,我会考虑浏览这两个字符串并计算每个字符出现的频率。

使用您的拼字游戏评论,如何: 获取输入中每个字符的总数,并将其与允许的字符列表中相同字符的计数进行比较。如果输入字符串包含的字符多于允许的字符列表,则输入字符串无效。

private static bool ValidateString(string input)
    {
        bool retValue = true;
        char[] validChars = { 'a', 'b', 'd' };
        foreach (var character in input)
        {
            //count the number of times the character occurs in the input string
            var characterCount = input.Count(c => c == character);
            //count the number of times the character occurs in the allowed char array
            var allowedCharacterCount = validChars.Count(c => c == character);
            //if the string contains more than the character array allows, immediately fail.
            if (characterCount > allowedCharacterCount)
            {
                retValue = false;
                break;
            }
        }
        return retValue;
    }

这可能不是最有效的执行方式,尤其是在字符串有效的情况下,因为它逐个字符遍历整个字符串。 但我认为它是功能性的。

我想

您可以通过转换为 char 数组来创建字符串中每个字母的计数来做到这一点,如果您的情况是您将有 3 个整数 (a,b,c(或带有 (0-25( 的 int 数组,其中 a=1 b=1 和 c=2,然后通过对另一个数组做同样的事情进行比较,并说如果数组你检查字符串的值是>=对于其中一个字符串 A 值,那么你很好,你可以继续检查 B,直到你检查你的 C 值 2 是否>= 到另一个值 C=1 并且你得到 false 所以它停止了。

您可以将搜索列表(即在目标字符串中搜索的字符列表(设置为数组或对象列表,而不仅仅是字符。然后,您可以为每个字符关联一个布尔值来指示"IsFoundInTarget" - 这样您就可以"标记"每个字符而不删除它。 最后,执行.Find(x=> x.Character == TheCharacterBeingSearchedFor && x.IsFoundInTarget == False)或类似操作来处理一个字符的多次出现。

我们可以使用默认方法包含var str="Ramesh";str.contains("s"(.计数((;

Linq 并不难理解,如果您愿意,可以将其分解为两个步骤

第一

//Check to see if the input values exist in the collection
var input = "abbc";
var collection = new List<char>() { 'c', 'b', 'a' };
bool doesContain = collection.Any(item => input.Contains((char)item));

包含将返回 true

第二

//check for duplicates in the input variable
var duplicatesList = input.GroupBy(s => s)
    .SelectMany(grp => grp.Skip(1)).ToList();

使用调试器,它将返回b