C# 按字母顺序、逆字母顺序和值的频率对的SortedDictionary进行排序

C# 按字母顺序、逆字母顺序和值的频率对的SortedDictionary进行排序,c#,dictionary,alphabetical,sorteddictionary,C#,Dictionary,Alphabetical,Sorteddictionary,我对C和哈希表/字典的概念是一个全新的概念,我一直在寻找一个直接的答案,但我找不到任何实际可行的解决方案,因为我对这个主题一无所知,所以我需要一个简单的解决方案,如果可能的话 此外,如果有区别,则字典中的字符串和int不是数据成员,甚至不是参数 更多说明: 整个程序是通过文本文件或直接用户输入导入单词,然后保存它们以及它们在字典/分类字典中出现的次数,然后允许用户按字母顺序、逆字母顺序或频率重新组织数据和/或将它们打印到控制台或将数据写入新的.txt文件 然而,现在我只是想让字典的排序工作正常

我对C和哈希表/字典的概念是一个全新的概念,我一直在寻找一个直接的答案,但我找不到任何实际可行的解决方案,因为我对这个主题一无所知,所以我需要一个简单的解决方案,如果可能的话

此外,如果有区别,则字典中的字符串和int不是数据成员,甚至不是参数

更多说明:

整个程序是通过文本文件或直接用户输入导入单词,然后保存它们以及它们在字典/分类字典中出现的次数,然后允许用户按字母顺序、逆字母顺序或频率重新组织数据和/或将它们打印到控制台或将数据写入新的.txt文件

然而,现在我只是想让字典的排序工作正常

输入示例: 又一个伟大的故事,又一次伟大的冒险

输出布局示例: 以字母A开头的单词: 又一次冒险 以字母G开头的字母: 伟大的 Ect

示例输出按字母顺序翻转: 以字母S开头的单词: 故事 以字母G开头的单词: 伟大的 ect

输出频率: 出现2次的字数: 另一个伟大的 出现1次的字数:
和冒险故事。

由于您并不总是在一个一致排序的庄园中显示数据,因此我认为没有任何令人信服的理由将数据存储在一个排序的庄园中。您最好只存储您想要的数据,然后在用户要求在特定分类的庄园中查看数据时对其进行排序。

希望这能有所帮助。我不确定这是解决问题的最佳方式,但它应该有助于您熟悉一些选项/了解为什么这里的一些人建议不要这样做。如果你让我们更多地了解你正在尝试做什么,我们可以更好地建议其他方法

using System;
using System.Collections.Generic;
using System.Linq;

namespace StackOverflow.Demos
{
    class Program
    {

        const string OutputFormat = "{0}: {1}";
        public static void Main(string[] args)
        {
            new Program();
            Console.WriteLine("Done");
            Console.ReadKey();
        }
        public Program()
        {
            SortedDictionary<string, int> dic = new SortedDictionary<string, int>();
            dic.Add("a", 1);
            dic.Add("b", 2);
            dic.Add("d", 2);
            dic.Add("c", 1);
            dic.Add("e", 1);
            dic.Add("f", 3);
            dic.Add("g", 4);
            dic.Add("h", 2);
            dic.Add("i", 2);

            OutputByKeyAsc(dic);
            OutputByKeyDesc(dic);
            OutputByValueFrequency(dic);
        }

        void OutputByKeyAsc(SortedDictionary<string, int> dic)
        {
            Console.WriteLine("OutputByKeyAsc");
            foreach (string key in dic.Keys)
            {
                Console.WriteLine(string.Format(OutputFormat, key, dic[key]));
            }
        }

        void OutputByKeyDesc(SortedDictionary<string, int> dic)
        {
            Console.WriteLine("OutputByKeyDesc");
            foreach (string key in dic.Keys.Reverse())
            {
                Console.WriteLine(string.Format(OutputFormat, key, dic[key]));
            }
        }

        void OutputByValueFrequency(SortedDictionary<string, int> dic)
        {
            Console.WriteLine("OutputByValueFrequency");

            IEnumerable<KeyValuePair<int,int>> values = 
                (
                    from sortedItem 
                    in 
                    (
                        from entry 
                        in dic 
                        group entry 
                        by entry.Value
                        into result
                        select new KeyValuePair<int,int>(result.Key , result.Count())
                    )
                    orderby sortedItem.Value descending
                    select sortedItem
                ).ToArray();

            foreach (KeyValuePair<int, int> value in values)
            {
                foreach (KeyValuePair<string, int> item in dic.Where<KeyValuePair<string, int>>(item => item.Value == value.Key))
                {
                    Console.WriteLine(string.Format(OutputFormat, item.Key, string.Format(OutputFormat, item.Value, value.Value)));
                }
            }
        }

    }
}
祝你好运/希望到目前为止你都很喜欢c

编辑

根据你问题中的新信息,我试图找到一个更简洁的解决方案:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace StackOverflow.Demos
{
    class Program
    {

        const string OutputFormat = "{0}: {1}";
        public static void Main(string[] args)
        {
            new Program("Another great story and another great adventure.");
            Console.WriteLine("Done");
            Console.ReadKey();
        }
        public Program(string userInput)
        {
            //break string into words
            IEnumerable<IGrouping<string, int>> words = Regex.Split(userInput, @"\W+").GroupBy(word => word.ToLowerInvariant(), word => 1); //nb converting word to lower case to avoid case sensitive comparisons in grouping - I can keep the original value(s) by replacing "word => 1" with "word => word" if needed

            Console.WriteLine("\nWords in alphabetic order");
            foreach (IGrouping<string, int> wordInfo in words.OrderBy(word => word.Key))
            {
                Console.WriteLine(string.Format(OutputFormat, wordInfo.Key,wordInfo.Count()));
            }

            Console.WriteLine("\nWords in descending alphabetic order");
            foreach (IGrouping<string, int> wordInfo in words.OrderByDescending(word => word.Key))
            {
                Console.WriteLine(string.Format(OutputFormat, wordInfo.Key, wordInfo.Count()));
            }

            Console.WriteLine("\nWords by frequency (desc)");
            foreach (IGrouping<string, int> wordInfo in words.OrderByDescending(word => word.Count()))
            {
                Console.WriteLine(string.Format(OutputFormat, wordInfo.Key, wordInfo.Count()));
            }
        }
    }
}
编辑

下面的代码与类中的功能相同,输出保存在程序中: 使用制度; 使用System.Collections.Generic; 使用System.Linq; 使用System.Text.RegularExpressions

namespace StackOverflow.Demos
{
    class Program
    {

        const string OutputFormat = "{0}: {1}";
        public static void Main(string[] args)
        {
            new Program("Another great story and another great adventure.");
            Console.WriteLine("Done");
            Console.ReadKey();
        }
        public Program(string userInput)
        {
            WordCounter myWordCounter = new WordCounter(userInput);
            Console.WriteLine("\n**Alphabetical**");
            foreach (KeyValuePair<string, int> wordInfo in myWordCounter.GetWordCountByWordAlphabeticalDesc())
            {
                Console.WriteLine(string.Format(OutputFormat,wordInfo.Key, wordInfo.Value));
            }
            Console.WriteLine("\n**Alphabetical Desc**");
            foreach (KeyValuePair<string, int> wordInfo in myWordCounter.GetWordCountByWordAlphabeticalDesc())
            {
                Console.WriteLine(string.Format(OutputFormat, wordInfo.Key, wordInfo.Value));
            }
            Console.WriteLine("\n**Frequency Desc**");
            foreach (KeyValuePair<string, int> wordInfo in myWordCounter.GetWordCountByFrequency())
            {
                Console.WriteLine(string.Format(OutputFormat, wordInfo.Key, wordInfo.Value));
            }
        }

    }

    public class WordCounter
    {
        string sentance;
        IEnumerable<IGrouping<string, int>> words;
        public WordCounter(string sentance)
        {
            this.sentance = sentance;
            GetWords();
        }
        void GetWords()
        {
            this.words = Regex.Split(this.sentance, @"\W+").GroupBy(word => word.ToLowerInvariant(), word => 1);
        }
        public IEnumerable<KeyValuePair<string, int>> GetWordCountByWordAlphabetical()
        {
            return this.words.OrderBy(word => word.Key).Select(wordInfo => new KeyValuePair<string,int>(wordInfo.Key, wordInfo.Count()));
        }
        public IEnumerable<KeyValuePair<string, int>> GetWordCountByWordAlphabeticalDesc()
        {
            return this.words.OrderByDescending(word => word.Key).Select(wordInfo => new KeyValuePair<string, int>(wordInfo.Key, wordInfo.Count()));
        }
        public IEnumerable<KeyValuePair<string, int>> GetWordCountByFrequency()
        {
            return this.words.OrderByDescending(word => word.Count()).Select(wordInfo => new KeyValuePair<string, int>(wordInfo.Key, wordInfo.Count()));
        }
    }
}

不清楚你想做什么或什么不起作用。你能展示你尝试过的吗?添加了更多描述。至于代码,我确信我现在基本上需要从头开始。输入、所需输出等示例将非常有用。字典实际上没有作为哈希表实现,它被实现为一个基于树的数据结构。我也不确定如何做到这一点。LINQ的OrderBy方法是获取任何数据结构并返回在某个特定区域中排序的所有值的有效方法。我已经尝试过了。然而,关于如何使用OrderBy方法的每个示例只会导致更多的混乱,因为我似乎永远无法理解参数是什么以及它们在做什么。另外,我看到的大多数示例都引用了我没有的已保存变量或数据成员。谢谢你的帮助帖子,但是我需要你在单独的TUI类中发布的代码。在inserted和fix to project specs中,for循环产生此错误foreach语句无法对void类型的变量进行操作,因为void不包含“GETenumerator”的公共定义。您能解释此错误的含义并给我一些如何修复此错误的建议吗?不用担心-我已将代码与for的UI放在同一层中演示目的。要使其作为库工作,请创建返回IEnumerable结果的函数,然后返回OrderBys的结果,或者将console.writeline替换为yield return语句,以获得更简单的解决方案。对不起,请您用更简单的方式解释一下,或者给我举个例子。不用担心,我已经将代码重构成一个单独的类-只需使用WordCount类-程序中的内容将向您展示如何使用该类。再次感谢您的帮助。我还没有能够测试最后一篇文章,但是如果遇到更多的问题,我会在这里发帖。