Question

I'll start off by saying I haven't quite wrapped my head around OOP.

I need a routine that iterates through each word in a string, checks to see if it is in my linked list and either adds it as a node if it is not or increases the count of the existing node if it is in the list.

Here is what I have:

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;
                        }
                    }

                }
            }
        }

Before this, I was attempting the addNode = new WordNode(stringWord); at the beginning of each iteration through the "for each word in string" loop, but that would re define the class and reset count to 1. Now, currently, I can't increase the count, because addNode.Count += 1; is undefined. I was hoping I could check to see if stringWord was in the linked list, and if so, increment stringWord.count by one, but that throws an error.

Looking at this now, I'm thinking the addNode.Count += 1; belongs in the while loop a few lines below it...

Here is my WordNode class:

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;
            }
        }
    }
Was it helpful?

Solution

Try this:

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);
            }
        }
    }
}

And alternative is to use linq:

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

OTHER TIPS

It sounds like you are just trying to practice making a linked list so this might not be helpful, but a much simpler solution is to use Key/Value pair like a dictionary.

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

The result of indexing the Words dictionary by the string will return the number of words.

This looks like a job for a Dictionary or here

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;
}

After running through the foreach myDict will contain counts for each word in the "bag of words."

Edit

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top