3

I'm new to programming, and I am trying to write a program that take in an array of strings (each index of the array being a word) and then count the occurrences of each word in the string. This is what I have so far:

        string[] words = 
        {
            "which", 
            "wristwatches", 
            "are", 
            "swiss", 
            "wristwatches"
        };

        Array.Sort (words);
        for (int i = 0; i < words.Length; i++) 
        {
            int count = 1;
            for(int j = 1; j < words.Length; j++)
            {
                if (words [i] == words [j])
                {
                    count++;
                }
            }
            Console.WriteLine ("{0}   {1}", words[i], count);
        } 

Ideally, I would like the output to be something like:

are 1

swiss 1

which 1

wristwatches 2

2
  • 2
    Cool. What help do you need? Commented Nov 14, 2012 at 5:11
  • Well, I can't seem to get the correct output, when I run it, I get are 1 swiss 2 which 2 wristwatches 3 wristwatches 3 Commented Nov 14, 2012 at 5:12

5 Answers 5

7

The problems with your code are (1) double-counting and (2) skipping the initial element in the nested loop.

You double-count because you ignore situations when i == j; you skip the initial element because you set int j = 1.

The shortest solution is to use LINQ, like this:

var counts = words
    .GroupBy(w => w)
    .Select(g => new {Word = g.Key, Count = g.Count()})
    .ToList();

Now you can print the results like this:

foreach (var p in counts) {
    Console.WriteLine("Word '{0}' found {1} times", p.Word, p.Count);
}
Sign up to request clarification or add additional context in comments.

3 Comments

@MitchWheat I mean "shortest" - it's a single statement :)
Hmm, I have not used or seen LINQ yet, but this is very interesting! :) Is there a way to modify the code I already wrote, or would it be too complex and messy?
@user1822739 Absolutely - add if (i != j && words [i] == words [j]) to avoid double-counting the same word, and use int j=0 in the nested loop to fix your code.
1

There are certainly more efficient ways of handling this (take a look at dasblinkenlight's answer for an extremely good one) but asssuming you'd like to keep relatively the same code, you should change your second for loop to something along these lines:

for(int j = i+1; j < words.Length; j++)
{
    if (words [i] == words [j])
    {
        count++;
    }
    else break;
}

Here are the two changes I made:

1) You should initialize j to i+1; You want to check if any of the rest of the Strings are equal to words[i], and the rest of the strings will start at i+1, not 1 (unless i=0).

2) For the sake of efficiency, you'll want to break out of the second loop if the two string aren't equal; since you sorted the array alphabetically, if the word you're currently looking at isn't equal, none of the ones after it will be either.

1 Comment

Wow, that makes a lot of sense! Thank you for your detailed explanation :)
0
var occrs = words.GroupBy(x => x.ToLower())
               .ToDictionary(g => g.Key, g => g.Count());
foreach(var pair in occrs)
    Console.WriteLine(pair.Key + " " +pair.Value);

Comments

0

For your understanding purpose use String.Compare()

  int Duplicate = words.Lenth + 1; //any value not in the range of the string array
  for (int i = 0; i < words.Length; i++) 
    {
        int count = 1;
        for(int j = 0; j < words.Length; j++)
        {
            if(i != j)  //to avoid same string comparison
            {
               if (string.Compare(words [i],words [j]) == 0)   //or else .Equals(0) 
               {
                  count++;
                  Duplicate = j;
               }
            }
        }
        if(i != Duplicate)
        {
           Console.WriteLine ("{0}   {1}", words[i], count);
        }
    } 

This will not print again the same value.

2 Comments

The string.Compare method is a really useful way to look at this, thank you
Hey @user1822739 check my edited answer. Now this will not print the duplicate values again on console.
0

Make use of dictionary data structure. Here the dictionary will store key as word and value as word count. Insert all the words in dictionary. If the word inserted word is new, set the value of the word key to 1 , otherwise increment the word-key value by 1.

        Dictionary<string, int> wordCount = new Dictionary<string, int>();

        // Insert a word in the dictionary if it exits, otherwise increment 
        //the count of the word

        for (int i = 0; i < words.Length; i++)
        {
            try
            {
                wordCount.Add(words[i], 1);
            }
            catch (Exception)
            {
                wordCount[words[i]] += 1;
            }
        }

        // display word and it's corresponding word count

        foreach (var item in wordCount)
        {
            Console.WriteLine ("{0}   {1}", item.Key, item.Value);
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.