C# 检查字符串是否包含列表中的所有字符,并考虑重复项
本文关键字:字符 是否 字符串 检查 包含 列表 | 更新日期: 2023-09-27 18:34:03
如何检查字符串是否可以由字符列表(或数组(中的字符组成,同时考虑重复的字母。
所以,假设我有字符串(或字符数组/列表/任何("abcc"和字符列表(或数组/字符串/任何东西,它都可以转换为任何("['c'],['b'],['a']"。如何相互检查这两个值,但也要考虑到"c"在 char 数组中只存在一次,因此它应该失败。
我知道我可以很容易地用任何一个".包含"并运行整个字符数组,在我去的时候从数组中删除该特定字符,或者使用"IndexOf"并做同样的事情,但我想知道是否有任何方法可以不从 char 数组中删除任何项目。
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 的字母 a
、 f
和 e
。 a
,因为我们需要 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