【问题标题】:Counting words using LinkedList使用 LinkedList 计算单词
【发布时间】:2013-11-21 12:15:13
【问题描述】:

我有一个 WordCount 类,它有字符串 wordDic 和 int 计数。接下来,我有一个列表。

我有另一个列表,里面有很多单词。我正在尝试使用 List 来计算 List 中每个单词的出现次数。

下面是我卡住的地方。

class WordCount
{
string wordDic;
int count;

}


    List<WordCount> usd = new List<WordCount>();

    foreach (string word in wordsList)
    {
        if (usd.wordDic.Contains(new WordCount {wordDic=word, count=0 }))
           usd.count[value] = usd.counts[value] + 1;
        else
            usd.Add(new WordCount() {wordDic=word, count=1});

    }

我不知道如何在代码中正确实现这一点,但我正在尝试搜索我的列表以查看 wordsList 中的单词是否已经存在,如果存在,则将 1 添加到计数中,但如果不存在则插入它在 usd 中,计数为 1。

注意: *我必须使用列表来执行此操作。我不允许使用其他任何东西,比如哈希表...*

【问题讨论】:

  • 首先,当你想使用word(我假设)时,你在循环中使用usd。您不能使用usd,因为List 没有wordDic 属性。二、count是什么类型?您为其分配一个字符串,然后将其分配为int
  • 是的,对于计数,我认为它应该为空,因为它是一个整数而不是字符串,但其余的东西我真的很困惑。 usd 是我的字典,而 wordsList 是我正在搜索的填充文本。 usd 保存单词以及每个单词的计数。查看我的更新。
  • int 不可为空。最好让它默认为 0。
  • @TheDude 我现在设置了正确的值 0 但我仍然不知道如何将 1 添加到与 wordList 中的 word 具有相同 wordDic 的 usd 对象。
  • @TheDude 您的解决方案正是我想要的。其他人都在建议其他方法,但我明确表示我不能使用列表以外的任何东西......我在代码的“其他”部分中的代码语法有一些错误。我认为括号没有正确关闭。

标签: c# list


【解决方案1】:

这是您编辑为仅使用列表之前的答案...顺便说一句,是什么推动了这一要求?

List<string> words = new List<string> {...};

// For case-insensitive you can instantiate with 
// new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
Dictionary<string, int> counts = new Dictionary<string, int>(); 
foreach (string word in words)
{
    if (counts.ContainsKey(word))
    { 
        counts[word] += 1;
    }
    else
    {
        counts[word] = 1;
    }
}

如果您只能使用列表,您可以使用List&lt;KeyValuePair&lt;string,int&gt;&gt; counts,这与字典相同(尽管我不确定它是否能保证唯一性)。解决方案将非常相似。如果您只能使用列表,则以下内容将起作用。

        List<string> words = new List<string>{...};
        List<string> foundWord = new List<string>();
        List<int> countWord = new List<int>();
        foreach (string word in words)
        {
            if (foundWord.Contains(word))
            {
                countWord[foundWord.IndexOf(word)] += 1;
            }
            else
            {
                foundWord.Add(word);
                countWord.Add(1);
            }
        }

使用您的 WordCount 类

        List<string> words = new List<string>{...};
        List<WordCount> foundWord = new List<WordCount>();
        foreach (string word in words)
        {
            WordCount match = foundWord.SingleOrDefault(w => w.wordDic == word);
            if (match!= null)
            {
                match.count += 1;
            }
            else
            {
                foundWord.Add(new WordCount { wordDic = word, count = 1 });
            }
        }

【讨论】:

  • 谁能告诉我这个解决方案有什么问题。这是在编辑列表之前创建的。
  • 我将其标记为备份,因为它是最快和最有效的方式。 Linq 很棒,但并不总是最有效的。它被过度使用,尤其是在错误的上下文中,即性能,
  • @Baldrick ...修正错别字
  • @codematrix:同意。 linq - 它被过度使用,但我发现它更安全。我更喜欢使用 linq 作为默认值(因为它更清晰且不易出错),然后在需要时使用其他技术进行性能调整。但我不喜欢盲目的必须用 linq 不惜一切代价做任何事情的哲学。
  • @HarrisCalvin。是的。对于SingleOrDefault,您需要在顶部添加 using System.Linq; 并引用 System.Core 程序集
【解决方案2】:

您可以使用 Linq 来执行此操作。

static void Main(string[] args)
{

    List<string> wordsList = new List<string>()
    {
        "Cat",
        "Dog",
        "Cat",
        "Hat"
    };

    List<WordCount> usd = wordsList.GroupBy(x => x)
                                   .Select(x => new WordCount() { wordDic = x.Key, count = x.Count() })
                                   .ToList();
}

【讨论】:

    【解决方案3】:

    使用 linq:假设您的单词列表:

    string[] words = { "blueberry", "chimpanzee", "abacus", "banana", "abacus","apple", "cheese" }; 
    

    你可以这样做:

    var count =
       from word in words
       group word.ToUpper() by word.ToUpper() into g
       where g.Count() > 0
       select new { g.Key, Count = g.Count() }; 
    

    (或者在您的情况下,选择 new WordCount()...这取决于您如何设置构造函数)...

    结果将如下所示:

    【讨论】:

      【解决方案4】:

      首先,您的所有班级成员都是私有的,因此,您无法在班级之外的某个地方访问它们。假设您也在 WordCount 类中使用它们。

      其次,您的count 成员是int。因此,follow 语句将不起作用:

      usd.count[value] = usd.counts[value] + 1;
      

      我认为你在 countscount 之间打错了。

      要解决您的问题,请找到回应您的话的柜台。如果存在,则增加count值,否则,创建新的。

      foreach (string word in wordsList) {
          WordCount counter = usd.Find(c => c.wordDic == word);
          if (counter != null) // Counter exists
              counter.count++;
          else
              usd.Add(new WordCount() { wordDic=word, count = 1 }); // Create new one
      }
      

      【讨论】:

        【解决方案5】:

        在使用“包含”方法时,您应该使用字典,因为它更快。

        用这个替换你的列表

        字典 usd = new Dictionary();

        foreach (string word in wordsList)
        {
            if (usd.ContainsKey(word.ToLower()))
               usd.count[word.ToLower()].count++;
            else
                usd.Add(word.ToLower(), new WordCount() {wordDic=word, count=1});
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-06
          • 2012-01-27
          • 2013-05-19
          相关资源
          最近更新 更多