使用LINQ检查字符串的字符是否包含在另一个字符串中 [英] Check if chars of a string contains in another string with LINQ

查看:780
本文介绍了使用LINQ检查字符串的字符是否包含在另一个字符串中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C#在命令行中制作Scrabble游戏.玩家必须输入一些单词,例如以下列表:

I'm making a Scrabble game in the command line with C#. The player must input some words like list below:

| Word   | Points |
| ------ | ------ |
| some   | 6      |
| first  | 8      |
| potsie | 8      |
| day    | 7      |
| could  | 8      |
| postie | 8      |
| from   | 9      |
| have   | 10     |
| back   | 12     |
| this   | 7      |

玩家收到的字母是:

sopitez

此值为字符串.我将检查单词中是否包含字母.为此,我尝试了以下代码:

This value is a string. I'll check if the letters contains in the words. For this I've tried this code:

String highst = (from word
                 in words 
                 where word.Contains(letters)
                 orderby points descending
                 select word).First();

但是我怎么做都行不通.此代码不会选择任何单词.我知道为什么sopitez不包含任何单词的原因.

But it doesn't work how I'll it. This code wouldn't select any word. I know the reason why because sopitez doesn't contain in any word.

我现在的问题是有一种方法可以检查字符串letters中的字符是否包含在whitout遍历字符的单词中.

My question now is there a way to check the chars in the string letters contain into the words whitout looping over the chars.

注意:每个字母在解决方案中最多只能使用一次.

Note: Each letter must be used at most once in the solution.

如果我计算结果,则必须为potsiepostie. (我必须为此写逻辑)

If I calculate the result it must be potsie or postie. (I must write the logic for that)

PS:我正在玩这个游戏: www.codingame.com/ide/puzzle/scrabble

P.S.: I'm playing this game: www.codingame.com/ide/puzzle/scrabble

推荐答案

这里的问题是Contains检查一个字符串是否包含另一个字符串.它不会检查它是否包含所有这些字符. 您需要用HashSet<char>替换字典中的每个字符串,并执行IsSubsetIsSuperset之类的集合比较,以确定字母是否匹配.

The problem here is that Contains checks to see if one string contains another; it is not checking to see if it contains all of those characters. You need to replace each string in your dictionary with a HashSet<char> and perform set comparisons like IsSubset or IsSuperset to determine if the letters are matching.

这是您正在做的事情:

string a= "Hello";
string b= "elHlo";
bool doesContain = b.Contains(a); //This returns false

这是您需要做的:

Here is what you need to do:

var setA = new HashSet<char>(a);
var setB = new HashSet<char>(b);    
bool isSubset = a.IsSubsetOf(b); //This returns true

更新 实际上,这是错误的,因为集合会删除重复的元素.但实际上您在滥用Contains.您将需要一些更复杂的序列比较,以允许重复的字母.

Update Actually, this is wrong, because sets remove duplicate elements. But essentially you are misusing Contains. You'll need some more complicated sequence comparison that can allow duplicate letters.

更新2 您需要进行字词/字母比较:

Update2 You need this for word/letters comparison:

//Compares counts of each letter in word and tiles
bool WordCanBeMadeFromLetters(string word, string tileLetters) {

    var tileLetterCounts = GetLetterCounts(tileLetters);
    var wordLetterCounts = GetLetterCounts(word);

    return wordLetterCounts.All(letter =>
        tileLetterCounts.ContainsKey(letter.Key)
        && tileLetterCounts[letter.Key] >= letter.Value);
}

//Gets dictionary of letter/# of letter in word
Dictionary<char, int> GetLetterCounts(string word){
    return word
        .GroupBy(c => c)
        .ToDictionary(
            grp => grp.Key,
            grp => grp.Count());
}

因此您的原始示例如下所示:

So your original example can look like this:

String highst = (from word
             in words 
             where WordCanBeMadeFromLetters(word, letters)
             orderby points descending
             select word).First();

这篇关于使用LINQ检查字符串的字符是否包含在另一个字符串中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆