【问题标题】:Adding and counting every word in a string to a linked list将字符串中的每个单词添加并计数到链表中
【发布时间】:2013-11-30 06:42:29
【问题描述】:

我首先要说我还没有完全理解 OOP。

我需要一个例程来遍历字符串中的每个单词,检查它是否在我的链表中,如果不是,则将其添加为节点,或者增加现有节点的计数,如果它在列表。

这是我所拥有的:

private void CountWords(string cleanString)
        {
            WordNode nextNode, prevNode;
            WordNode addNode;
            foreach (string stringWord in cleanString.Split(' '))
            {
                if (head == null)
                {
                    // No items in list, add to the beginning
                    addNode = new WordNode(stringWord);
                    head = addNode;
                }
                else
                {
                    if (String.Compare(stringWord, head.Word) < 0)
                    {
                        // If stringWord belongs at the beginning of the list, put it there
                        addNode = new WordNode(stringWord);
                        addNode.NextWord = head;
                        head = addNode;
                    }
                    else if (String.Compare(stringWord, head.Word) == 0)
                    {
                        // If stringWord is equal to head.Word, increase count
                        addNode.Count += 1;
                    }
                    else
                    {
                        prevNode = head;
                        nextNode = head.NextWord;
                        // If it doesn't belong at the beginning, cycle through the list until you find where it does belong
                        while ((nextNode != null) && (String.Compare(nextNode.Word, addNode.Word) < 0))
                        {
                            prevNode = nextNode;
                            nextNode = nextNode.NextWord;
                        }
                        if (nextNode == null)
                        {
                            prevNode.NextWord = addNode;
                        }
                        else
                        {
                            prevNode.NextWord = addNode;
                            addNode.NextWord = nextNode;
                        }
                    }

                }
            }
        }

在此之前,我尝试 addNode = new WordNode(stringWord); 在每次迭代开始时通过“for each word in string”循环,但这会重新定义类和将计数重置为 1。目前,我无法增加计数,因为 addNode.Count += 1; 未定义。我希望我可以检查 stringWord 是否在链接列表中,如果是,则将 stringWord.count 加一,但这会引发错误。

现在看这个,我认为 addNode.Count += 1; 属于 while 循环下面几行...

这是我的 WordNode 类:

class WordNode
    {
        // constants

        // variables
        private string data;            // this is our only data, so also key
        private int count;
        private WordNode next;          // this is reference to next Node

        // constructors
        public WordNode(string newValue)
        {
            Word = newValue;
            count = 1;
            NextWord = null;
        }

        // methods
        public string Word
        {
            get
            {
                return data;
            }
            set
            {
                data = value;
            }
        }

        public int Count
        {
            get
            {
                return count;
            }
            set
            {
                count = value;
            }
        }

        public WordNode NextWord
        {
            get
            {
                return next;
            }
            set
            {
                next = value;
            }
        }
    }

【问题讨论】:

    标签: c# text-parsing string-parsing singly-linked-list


    【解决方案1】:

    这看起来像是 Dictionaryhere 的工作

    Dictionary<string,int> myDict = new Dictionary<string,int>();
    
    foreach(string str in listOfWords)
    {
       myDict.add(str,0);
    }
    
    foreach(string x in cleanText.split(' '))
    {
    if(myDict.ContainsKey(x))
       myDict[x]+=1;
    }
    

    在运行 foreach 之后,myDict 将包含“词袋”中每个词的计数。

    编辑

    if(myDict == null)
       myDict = new Dictionary<string,int>(); //assuming running tally at higher scope.
    
    
    foreach(string x in cleanText.split(' '))
    {
    if(myDict.ContainsKey(x))
       myDict[x]+=1;
    else
       myDict.add(x,1);
    }
    

    【讨论】:

    • 这仅适用于listOfWords 已经包含所有生成的单词,而您没有代码来确保发生。为什么不随时添加新单词的计数?
    【解决方案2】:

    试试这个:

    private void CountWords(string cleanString)
    {
        foreach (string stringWord in cleanString.Split(' '))
        {
            if (head == null)
            {
                head = new WordNode(stringWord);
            }
            else
            {
                var last = (WordNode)null;
                var current = head;
                do
                {
                    if (current.Word == stringWord)
                    {
                        break;
                    }
                    last = current;
                    current = current.NextWord;
                } while (current != null);
                if (current != null)
                {
                    current.Count++;
                }
                else
                {
                    last.NextWord = new WordNode(stringWord);
                }
            }
        }
    }
    

    另一种方法是使用 linq:

    var query =
        cleanString
            .Split(' ')
            .ToLookup(x => x)
            .Select(x => new
            {
                Word = x.Key,
                Count = x.Count(),
            });
    

    【讨论】:

    • 谢谢!这就是诀窍,虽然它们不是按字母顺序排列的(但我没有在我的原始帖子中指定)。
    • 在我的 linq 方法中添加排序方法很容易。
    【解决方案3】:

    听起来你只是想练习制作一个链表,所以这可能没有帮助,但更简单的解决方案是像字典一样使用键/值对。

    Dictionary<string, int> Words = new Dictionary<string, int>();
    string wordsList = "a list of words for testing a list of words for testing";
    foreach (string word in wordsList.Split(' '))
    {
       if (Words[word] == null)
          Words[word] = 1;
       else
          Words[word] += 1;
    }
    System.Console.WriteLine("testing: {0}", Words["testing"]); //result- testing: 2
    

    按字符串索引单词字典的结果会返回单词的个数。

    【讨论】:

    • 这将在第一次迭代时抛出KeyNotFoundException。你在想Hashtable 的工作方式吗?如果您之前定义了int count,那么您可以可靠地分配Words[word] = Words.TryGetValue(word, out count) ? count + 1 : 1。 (或者甚至只是调用它并添加一个,因为它会将count 设置为default(int),如果没有找到任何东西,则为0,尽管对此有一种有点笨拙的感觉)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多