细化列表的最简单方法是什么;基于字符频率和位置的内容(单词)?(C#)

本文关键字:频率 位置 单词 方法 最简单 列表 是什么 细化 于字符 字符 | 更新日期: 2023-09-27 18:29:16

我正在为我的入门编程课程编写一个控制台环境Hangman游戏。玩家选择他们想要的单词长度和猜测次数"简易模式"足够简单。。。生成一个随机数用作列表的索引,并检查所选单词的长度是否正确。然而,"硬模式"需要随着游戏的进行对列表进行细化,根据猜测的字母选择最大的可能性列表。

我应该注意,我们没有使用C#List类,而是创建基于数组的结构:

    struct ListType
    {
        public type[] items;
        public int count;
    }
    //defined as:
    ListType myList = new ListType();
    myList.items = new type[max value];
    myList.count = 0;

无论如何,这里有一个"硬模式"应该走的方式的例子:

Word List:
hole
airplane
lame
photos
cart
mole
(player chooses word length of 4)
Word List (refined):
hole
lame
cart
mole
(player guesses "l", then "e")
Word List (refined):
hole
mole

省略"Lame"是因为更多的单词具有"…le…"模式。对我来说有意义的技术(但并没有按照我想要的方式工作)是将每个单词的模式存储到一个数组中(即:"摩尔"answers"洞"=0011,"跛脚"=1001),并对重复的单词进行计数以确定更大的列表。

我应该这样做吗?我是编程新手,有不到一年的编程经验,所以我想答案是这样的。

谢谢!!

细化列表的最简单方法是什么;基于字符频率和位置的内容(单词)?(C#)

有几种方法可以解决这个问题。一个简单的方法是跟踪所有候选单词的列表,计算该单词的匹配序列数量,并记录最佳匹配序列。这样,当单独的最佳序列不是一个足够好的测量工具时,您既可以对最佳序列进行排序,也可以对序列数量进行排序。我希望如何修改这段代码以便只按最佳顺序排序变得显而易见。

首先,我设置了一个测试用例,比如:

// mimic the scenario given by the QA
string[] wordList = new string[] { "hole", "airplane", "lame", "photos", "cart", "mole" };
int wordLength = 4;
List<char> requiredCharacters = new List<char>{ 'l', 'e'};

之后,我过滤单词列表并计算最佳匹配,最后将其组合在一起以产生所需结果:

// filter all words that dont match the required length
var candidateWords = wordList.Where(x => x.Length == wordLength);
// define a result set holding all the words and all their matches
Dictionary<string, List<int>> refinedWordSet = new Dictionary<string, List<int>>();
foreach (string word in candidateWords)
{
    List<int> matches = new List<int>() { 0 };
    int currentMatchCount = 0;
    foreach (char character in word)
    {
        if (requiredCharacters.Contains(character))
        {
            currentMatchCount++;
        }
        else
        {
            // if there were previous matches
            if (currentMatchCount > 0)
            {
                // save the current match
                matches.Add(currentMatchCount);
                currentMatchCount = 0;
            }
        }
    }
    // if there was a match at the end
    if (currentMatchCount > 0)
    {
        // save the last match
        matches.Add(currentMatchCount);
    }
    refinedWordSet.Add(word, matches);
}   
// sort by a combination of the total amount of matches as well as the highest match
var goupedRefinedWords = from entry in refinedWordSet
                            group entry.Key by new { Max = entry.Value.Max(), Total = entry.Value.Sum() } into grouped
                            select grouped;
foreach (var entry in goupedRefinedWords)
{
    Console.WriteLine("Word list with best match: {0} and total match {1}: {2}", 
        entry.Key.Max,
        entry.Key.Total,
        entry.Aggregate("", (result, nextWord) => result += nextWord + ", "));
}
Console.ReadLine();

注意代码中的注释

因此,您可以在数组中查找与猜测模式匹配的字符串。

在"le"的特定情况下,您可以简单地使用String.IndexOf()。如果您需要更多的cmplex模式。。比如"*le?"(其中*和?遵循类似DOS的通配符模式),您可以使用动态结构化的regex模式(如果在接近实时的系统中使用,则很容易,但性能很高)或字符扫描(从屏幕上读取每个字符并与您的模式相匹配)(在接近RT的系统中,对于少量元素来说,更困难、更难维护、性能更好)。

由于这是家庭作业,我现在根本不担心性能评测。

此外,这个结构看起来非常愚蠢。对于这种类型的东西,肯定有更好的构造。就像List<String>,或者只是String[]。。。两者都具有CCD_ 4性质。