您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 4浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

如何解读任何单词

寒冰屋 发布时间:2021-07-12 22:58:37 ,浏览量:4

目录

介绍

使用代码

测试/实施

介绍

我永远找不到在互联网上解读单词的好方法。每个算法要么是蛮力,要么是排列。

蛮力的问题在于它是一个猜谜游戏......非常慢,或者如果你幸运的话,非常快。

排列的问题在于,一旦超过7个字符,就会使用大量内存。例如,一个12个字符的加扰单词有479,001,600个配置!

我终于明白,如​​果你对打乱的单词进行排序,然后对字典条目进行排序,那么如果我们将任何排序的字典条目等同于我们的排序打乱,那么它们一定是匹配的!

可能有一些奇特的机器学习算法可以做到这一点,但我的方法完美而即时。

使用代码

您需要将您最喜欢的字典嵌入到您的项目中(为了速度和便携性)。

那里有很多免费的字典文件;这是我使用的... https://github.com/dwyl/english-words。

直接链接... https://raw.githubusercontent.com/dwyl/english-words/master/words.txt。

主力就是UnscrambleWord方法;这将负责加载字典、过滤然后对结果进行排序并将它们存储在一个List对象中,该对象将从调用中返回给您。

class Unscramble
{
     private static bool _dictionaryLoaded = false;
     private static string _wordToUnscramble = "";
     private static int _totalEntries = 0;
     private static Dictionary _sortedDictionary =
                                       new Dictionary();
     private static List _results = new List();
     private static Stopwatch _stopwatch;

     //====================================================================================
     /** We don't really need a constructor **/
     //public Unscramble(string wordToUnscramble)
     //{
     //    _WordToUnscramble = wordToUnscramble;
     //}

     //====================================================================================
     public List UnscrambleWord(string wordToUnscramble, bool useFiltering = true)
     {
         _stopwatch = Stopwatch.StartNew();

         if (string.IsNullOrEmpty(_wordToUnscramble))
         {
             _wordToUnscramble = wordToUnscramble;
         }
         else if (!_wordToUnscramble.Equals
              (wordToUnscramble, StringComparison.OrdinalIgnoreCase) && useFiltering)
         {   //If re-using the object and the word is different,
             //we'll need to reload the dictionary
             _dictionaryLoaded = false;
             _wordToUnscramble = wordToUnscramble;
             _results.Clear();
         }
         else if (_wordToUnscramble.Equals
                 (wordToUnscramble, StringComparison.OrdinalIgnoreCase))
         {
             _results.Clear(); //we should clear the results array so they don't stack
         }

         if (!_dictionaryLoaded) //the first call will be slightly slower
             LoadEmbeddedDictionary(wordToUnscramble.ToUpper(), useFiltering);

         string scrambleSorted = SortWord(wordToUnscramble);

         //var kvp = SortedDictionary.FirstOrDefault
         //(p => SortedDictionary.Comparer.Equals(p.Value, scrambledSort));
         var matchList = _sortedDictionary.Where
             (kvp => kvp.Value == scrambleSorted).Select(kvp => kvp.Key).ToList();

         if (matchList.Count > 0)
         {
             foreach (string result in matchList)
             {
                 System.Diagnostics.Debug.WriteLine($"> Match: {result}");
                 _results.Add(result);
             }

             _stopwatch.Stop();
             System.Diagnostics.Debug.WriteLine($"> Elapsed time: {_stopwatch.Elapsed}");
             return _results;
         }
         else //no matches
         {
             _stopwatch.Stop();
             _results.Clear();
             System.Diagnostics.Debug.WriteLine($"> Elapsed time: {_stopwatch.Elapsed}");
             return _results;
         }
     }

     //==================================================================================
     private static void LoadEmbeddedDictionary(string wordText, bool filter = false)
     {
         char[] delims = new char[1] { '\n' };
         string[] chunks;
         int chunkCount = 0;
         if (filter)
             chunks = global::Utility.Properties.Resources.
                                      DictionaryNums.ToUpper().Split(delims);
         else
             chunks = global::Utility.Properties.Resources.
                                      DictionaryNums.ToUpper().Split(delims);

         System.Diagnostics.Debug.WriteLine($"> Length filter: {wordText.Length}");
         _sortedDictionary.Clear();
         foreach (string str in chunks)
         {
             chunkCount++;
             if (filter)
             {
                 //we're assuming the word will have at least 3 characters...
                 //I mean would you really need this program if it was only two?
                 if ((str.Length == wordText.Length) &&
                      str.Contains(wordText.Substring(0, 1)) &&
                      str.Contains(wordText.Substring(1, 1)) &&
                      str.Contains(wordText.Substring(2, 1))) //just checking the 1st,
                                    //2nd & 3rd letter will trim our search considerably
                 {
                     try
                     {
                         _sortedDictionary.Add(str, SortWord(str));
                     }
                     catch
                     {
                         //probably a key collision, just ignore
                     }
                 }
             }
             else
             {
                 try
                 {
                     _sortedDictionary.Add(str, SortWord(str));
                 }
                 catch
                 {
                     //probably a key collision, just ignore
                 }
             }
         }
         System.Diagnostics.Debug.WriteLine($">
         Loaded {_sortedDictionary.Count} possible matches out of {chunkCount.ToString()}");
         _totalEntries = chunkCount;
         _dictionaryLoaded = true;
     }

     //=================================================================================
     private static string SortWord(string str)
     {
         return String.Concat(str.OrderBy(c => c));

         /*** Character Array Method ***
         return String.Concat(str.OrderBy(c => c).ToArray());
         *******************************/

         /*** Traditional Method ***
         char[] chars = input.ToArray();
         Array.Sort(chars);
         return new string(chars);
         ***************************/
     }

     #region [Helper Methods]
     //=================================================================================
     public TimeSpan GetMatchTime()
     {
        return _stopwatch.Elapsed;
     }

     //=================================================================================
     public List GetMatchResults()
     {
        return _results;
     }

     //=================================================================================
     public int GetMatchCount()
     {
        return _results.Count;
     }

     //=================================================================================
     public int GetFilterCount()
     {
        return _sortedDictionary.Count;
     }

     //=================================================================================
     public int GetDictionaryCount()
     {
        return _totalEntries;
     }
     #endregion
}

测试/实施

要驱动代码,你会这样做......

string scrambled = "mctmouicnaino";
Unscramble obj1 = new Unscramble();
List results = obj1.UnscrambleWord(scrambled);
if (results.Count > 0)
{
    Console.WriteLine($"> Total matches: {obj1.GetMatchCount()}");
    foreach (string str in results)
    {
        Console.WriteLine($">> {str}");
    }
    Console.WriteLine($"> Total time: {obj1.GetMatchTime()}");
    Console.WriteLine($"> Filtered set: {obj1.GetFilterCount()}
                          out of {obj1.GetDictionaryCount()}");
}
else
{
    Console.WriteLine("> No matches available:
            Check your spelling, or the dictionary may be missing this word.");
}

添加更多的LINQ方法来更改顺序、取顶部结果等,但这应该是对任何解读引擎基础的一个很好的补救措施。

https://www.codeproject.com/Tips/5299463/How-to-Unscramble-Any-Word

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.0648s