【问题标题】:Given an array that is all words in the dictionary, assign a value to each word based on a numerical value assigned to each character in the alphabet给定一个包含字典中所有单词的数组,根据分配给字母表中每个字符的数值为每个单词分配一个值
【发布时间】:2022-01-24 02:55:40
【问题描述】:

我在字典中取出了一个单词列表,并将它们变成了一个庞大的数组。我反过来创建了一个贯穿每个单词的脚本,并分解了哪些字母字符出现最多。所以我有一个分配给每个字符的值列表,其中 26 是分配给最常见字母 s 的值,而 1 是分配给最不常见字母 q 的值。

我又制作了一个脚本,遍历所有单词并分配这些值,然后可以在控制台上输出它们,如“fudge: 72”

            foreach (string word in masterList)
        {
            int wordValue = 0;
            foreach (char letter in word)
            {
                if (letter == 'a')
                {
                    wordValue += 23;
                }
                if (letter == 'b')
                {
                    wordValue += 10;
                }
                if (letter == 'c')
                {
                    wordValue += 14;
                }
                if (letter == 'd')
                {
                    wordValue += 16;
                }
                if (letter == 'e')
                {
                    wordValue += 25;
                }
                if (letter == 'f')
                {
                    wordValue += 7;
                }
                if (letter == 'g')
                {
                    wordValue += 9;
                }
                if (letter == 'h')
                {
                    wordValue += 24;
                }
                if (letter == 'i')
                {
                    wordValue += 20;
                }
                if (letter == 'j')
                {
                    wordValue += 2;
                }
                if (letter == 'k')
                {
                    wordValue += 8;
                }
                if (letter == 'l')
                {
                    wordValue += 18;
                }
                if (letter == 'm')
                {
                    wordValue += 11;
                }
                if (letter == 'n')
                {
                    wordValue += 17;
                }
                if (letter == 'o')
                {
                    wordValue += 21;
                }
                if (letter == 'p')
                {
                    wordValue += 13;
                }
                if (letter == 'q')
                {
                    wordValue += 1;
                }
                if (letter == 'r')
                {
                    wordValue += 22;
                }
                if (letter == 's')
                {
                    wordValue += 26;
                }
                if (letter == 't')
                {
                    wordValue += 19;
                }
                if (letter == 'u')
                {
                    wordValue += 15;
                }
                if (letter == 'v')
                {
                    wordValue += 5;
                }
                if (letter == 'w')
                {
                    wordValue += 6;
                }
                if (letter == 'x')
                {
                    wordValue += 4;
                }
                if (letter == 'y')
                {
                    wordValue += 12;
                }
                if (letter == 'z')
                {
                    wordValue += 3;
                }
            }
            Console.WriteLine(word + ": " + wordValue);
        }

但是,我想将“wordValue”分配给每个“word”,然后按最高值“wordValue”对数组进行排序。

【问题讨论】:

  • 将每个单词添加到列表,其中 Word 是您的内部类,有 2 个成员 string wordint wordValue。然后你可以使用 LINQ 按 wordValue 的降序打印列表。
  • 我没有关注你想要做的事情。如果你有一个单词列表并且……”我反过来创建了一个脚本,遍历每个单词并分解哪些字母字符出现最多。所以我有一个分配给每个字符的值列表,其中 26 是分配给最常见字母 s 的值,而 1 是分配给最不常见字母 q 的值。” ... ? …
  • 看起来你已经硬编码并发布了这种关系......即......,“a = 23”,“b = 10”等......但是,如果你有一个“不同”的单词列表,那么每个字母的值不会与您当前代码显示的值“不同”吗?您是否打算用每个新的单词列表重写您的代码?在我看来,您需要一种方法来根据给定的单词列表“创建”这种关系,因为它会随着每个“不同”的单词列表而“改变”?
  • 还有其他问题,例如……如果单词列表中不存在字母表中的所有字符,您会使用什么“比例”?我建议采用一种方法,该方法获取单词列表并返回Dictionary<char, int>,其中每个char 将是a-z?int 将是每个字符在给定单词列表中的使用次数。在你“创建”了这个Dictionary<char, int> 之后,你可以遍历列表中的每个单词并使用字典为其分配一个值。 Dictionary<char, int> 的点对于任何给定的单词列表都是不同的和唯一的。
  • 如果两个或多个字母被使用了相同的次数怎么办?您将如何确定“什么”值来赋予每个具有相同使用次数的字符?这开始闻起来很可疑,你需要澄清你想如何处理必然会发生的歧义。

标签: c# arrays sorting multidimensional-array


【解决方案1】:

您可以稍微压缩您的得分。每个字母在最左边的 q 和最右边的 s 的字符串中获得它的位置分数:

class WordCalc{

    private string _scores = "qjzxvwfkgbmypcudnltiorahes";

    public int WordScore(string word) => word.Sum(c => _scores.IndexOf(c)+1);

所以你可以用它来排序单词列表:

var calc = new WordCalc();
words.OrderByDescending(w => calc.WordScore(w));

如果你想加快查找速度,比如你有很多词要做:

class WordCalc{

    private Dictionary<char, int> _scores;
    

    public WordCalc(string scoreLetters = "qjzxvwfkgbmypcudnltiorahes"){
      _scores = scoreLetters
        .Select((c,i) => new { C= c, S = i+1})
        .ToDictionary(at => at.C, at => at.S);
    }

    public int WordScore(string word) => word.Sum(c => _scores.TryGetValue(c, out var s) ? s : 0);

我们制作了一个将字符映射到分数的字典,并使用它。当 IndexOf 没有找到我们 +1 的字符时返回 -1,因此未知字符得分为 0。如果查找未知字符,字典会崩溃,因此我们尝试获取该值,如果成功,我们使用它,否则我们使用 0

还有一个技巧依赖于 c# 能够将 chars 和 int 视为等效

class WordCalc
{

    private int[] _scores = new int[65535];


    public WordCalc(string scoreLetters = "qjzxvwfkgbmypcudnltiorahes")
    {
        for (int x = 0; x < scoreLetters.Length; x++)
            _scores[scoreLetters[x]] = x+1;
        
    }

    public int WordScore(string word) => word.Sum(c => _scores[c]);
}

我们声明了一个足以容纳每个字符的 int 数组;大多数情况下它们是零,但随后我们运行一个循环,该循环将 char 拉到索引 x 并使用它来索引数组。因为 q 作为 char 的值为 113,所以 _scores 中的数组索引 113 被设置为 x+1 即 1。这样继续下去,我们的“大部分为零”映射数组中有一些非零值,它们是这些字母的分数。 j 是 106,所以索引 scores[106]2 等等

当我们对一个单词进行评分时,我们可以快速从中获取一个字符 - 例如h 在 "hello" 中,C# 隐式将 h 转换为 104,转到 _scores[104],找到 24(因为 h 在 scoreLetters 中位于第 23 位),这就是该字母的分数.这种查找甚至比字典还要快..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多