Reputation: 61
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
Upvotes: 3
Views: 12460
Reputation: 373
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);
}
Upvotes: 0
Reputation: 41822
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.
Upvotes: 0
Reputation: 9382
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.
Upvotes: 1
Reputation: 39085
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);
Upvotes: 0
Reputation: 726479
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);
}
Upvotes: 7