Anthony K.
Anthony K.

Reputation: 1

Console application that counts the number of words in a sentence. (C#)

This program checks every character in a sentence. Every time the character is a space(" ") the numberOfWords (variable) will be incremented by 1. Is this the right way to do it?

        string sentence;
        int numberOfWords;
        int sentenceLength;
        int counter;
        string letter;


        Console.Write("Sentence :");
        sentence = Console.ReadLine();
        sentenceLength = sentence.Length;
        numberOfWords = 1;
        counter = 0;

        while (counter < sentenceLength)
        {
            letter = Convert.ToString(sentence[counter]);
            if (letter == " ")
            {
                numberOfWords++;
                counter++;
            }
            else
            {
                counter++;
            }

        }

        Console.Write("Number of words in this sentence :");
        Console.WriteLine(numberOfWords);
        Console.ReadLine();

Upvotes: 0

Views: 973

Answers (2)

InBetween
InBetween

Reputation: 32750

Well, the easy answer is; don't reinvent the wheel, use existing tools:

var numberOfWords = 
   sentence.Split(
       ' ',                            
       StringSplitOptions.
           RemoveEmptyEntries).Length;

But that would be cheating...

So, taking your code, there are a few things that need to be fixed:

First, don't make your method do too many things. There is no reason why a method counting words should know anything about how to output the result to any given user interface. Simply make a method that knows how to count words and returns the number of words:

public static int CountWords(string sentence) { ...}

Now you can reuse this method in any type of application; console, windows forms, WPF, etc.

Second, take corner or trivial cases out of the equation fast. Null sentences are either an error or have no words. Make a choice on how you want to process this scenario. If 0 words makes sense, you can solve a few cases in one strike:

    if (string.IsNullOrWhiteSpace(sentence))
        return 0;

Third, don't perform unnecessary conversions; converting chars to strings simply to perform an equality check with " " is wasteful. Compare chars directly (' '), or use the aptly named char.IsWhiteSpace(+) method.

Fourth, your logic is flawed. Double spaces, leading spaces, etc. will all give you wrong results. The reason being that your condition on when to count a word is faulty. Encountering a whitespace doesn't necessarily mean a new word is on the way; another whitespace might be waiting, you’ve already encountered a white space in the previous iteration, the sentence might end, etc.

In order to make your logic work you need to keep track of what happened before, what’s happening now and what will happen next... if that sounds messy and over complicated, don’t worry, you are absolutely right.

A simpler way is to shift your logic just a little; let’s say we encounter a new word everytime we find a non whitespace(*) that is preceded by a whitespace. What happens after is irrelevant, so we’ve just made things a lot easier:

var counter = 0;
var words = 0;,
var previousIsWhiteSpace = false;

while (counter < sentence.Length)
{
    if (char.IsWhiteSpace(sentence[counter]))
    {
        previousIsWhiteSpace = true;
    }
    else if (previousIsWhiteSpace) 
    {
         words += 1;
         previousIsWhiteSpace = false;
    }

    counter += 1;
}

Put it all together and you are done.

(+) this will actually flag more than a regular space as a valid whitespace; tab, new line, etc. will all return true.

(*) I’m ignoring scenarios involving punctuation marks, separators, etc.

Upvotes: 1

John
John

Reputation: 638

Just sticking with the style of your implementation, assuming the input is only split by single spaces, it's much nicer to just split your sentence string on each white space character.

string[] words = sentence.Trim().Split(null);

using null as the argument, white space will be used to split. Trim() removes trailing and leading space characters. Then, using words.Length you can easily get how many words there are separated by white space. However, this won't account for double spaces or empty sentences. Removing double or more spaces is best achieved with regex.

RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);     
sentence = regex.Replace(sentence, " ");

Upvotes: 0

Related Questions