Thread: Counting occurances of two letters in a particular order?

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    42

    Counting occurances of two letters in a particular order?

    Newbie here again. Working on homework again and loking for some hints. My instructor suggested the concept is a "state engine" and I have searched the boards and google without finding much.

    Instructions are to write a program that reads input and count all occurances of the letters "is" in that order. ex. Mississippi would be 2.

    Here is my code so far. I am getting a count on all "i" and "s". Trying to figure out how to code it so its:

    Check for "i"
    check next letter
    if "s" add 1 to count, if not continue checking.
    exit at #

    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	char ch;
    	char next_ch;
    	int is_count = 0;
    	
    
    	printf("Key in your word or phrase:  \n");
    	
    	while ((ch = getchar()) !='#')
    	
    	{
    		if (ch == 'i')
    			is_count++;
    		
    		if (ch == 's')
    			is_count++;
    	}
    		printf("\"is\" count %d\n", is_count);
    
    	getchar();
    	getchar();
    	return 0;
    }

  2. #2
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    In your example, you are counting 's' and 'i'... whether or not they follow each other.

    You want to make sure the letters follow each other.
    Check for 's', and if true, check next letter for 'i' (nested IF).

    The state engine approach is overkill in this case.

  3. #3
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198

    Smile

    Quote Originally Posted by d2rover View Post
    Newbie here again. Working on homework again and loking for some hints. My instructor suggested the concept is a "state engine" and I have searched the boards and google without finding much.

    Instructions are to write a program that reads input and count all occurances of the letters "is" in that order. ex. Mississippi would be 2.

    Here is my code so far. I am getting a count on all "i" and "s". Trying to figure out how to code it so its:

    Check for "i"
    check next letter
    if "s" add 1 to count, if not continue checking.
    exit at #

    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	char ch;
    	char next_ch;
    	int is_count = 0;
    	
    
    	printf("Key in your word or phrase:  \n");
    	
    	while ((ch = getchar()) !='#')
    	
    	{
    		if (ch == 'i')
    			is_count++;
    		
    		if (ch == 's')
    			is_count++;
    	}
    		printf("\"is\" count %d\n", is_count);
    
    	getchar();
    	getchar();
    	return 0;
    }
    Hi, I'm assuming you ran the code above and got the wrong answer?

    This was an interesting problem for me, because I've solved it using only the
    C functions that you have been shown so far

    It's these small programs that, at first glance seem easy to me. Until I try it...

    I had to get a pen and paper, wrote down all your variables as a box, and stepped
    through each of my iterations.

    Once it did that, I found out why all of my input worked, EXCEPT for mississippi!

    I'd like to step you through this so you can learn.

    Here are some hints for my final code:

    above main() I put:

    Code:
    #define TRUE 1
    #define FALSE 0

    EDIT: Inside main() I put:


    Code:
    	char ch;
    //	char next_ch;
    	int is_i_count = FALSE;
    	int is_s_count = FALSE;

    next, test for 'i' or 's' then set the counts if TRUE after each if.

    Finally, and this is a big hint, you'll need to add another if( ) to test
    if both of the previous test are TRUE.

    I wont show you my final code until you get your pen and paper, as I had to do
    just now, and design your code.
    Last edited by Char*Pntr; 09-27-2010 at 01:06 PM. Reason: clarification

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    State machine is a bit of overkill but an OK way to think about it. There's a state where you've just seen an 'i' and a state where you haven't. You only want to increment your counter when you're in the "just seen an i state" and then you read an 's'.

    You can do this by just adding a flag that tells you if you're in the "just saw an i state" or not. If you see an 'i', unconditionally set the i-state flag and loop to read the next character. Otherwise, if you're in i state and the current character is an 's', update your count. Also, regardless of the current character if you're in i-state and you didn't read another i, reset the i-state flag.

    Something like this would get it done with minimal changes to your code (untested pseudo-code):
    Code:
    while ((read char into ch) isn't #)
    {
        if (ch is 'i') set i state
        else if (i state is set)
        {
            clear i state
            if (ch is 's') increment counter
        }
    }
    Be sure to test with input like "iis" to make sure you're correctly handling multiple runs of i's before the "is" you want to count.

    you could also read the whole line into a string and abuse strncmp or strstr but I'm guessing your teacher wants to you do something closer to my 1st idea.

  5. #5
    Registered User
    Join Date
    Sep 2010
    Posts
    42
    Quote Originally Posted by nonoob View Post
    In your example, you are counting 's' and 'i'... whether or not they follow each other.

    You want to make sure the letters follow each other.
    Check for 's', and if true, check next letter for 'i' (nested IF).

    The state engine approach is overkill in this case.
    I think I understand the logic portion:

    Check to see if character is an "i"

    if true check next character to see if its an "s"

    (if false loop back and check next character for 'i")

    if true add 1 to counter and move to next character

    (if false loop back and check next character for "i" again)

    Maybe I cant see the forrest for the trees but it seems like it should be a very simple program to code.

  6. #6
    Registered User
    Join Date
    Sep 2010
    Posts
    42
    How can I tell the code if ch == i to advance ch to the next letter and check for "s"?

  7. #7
    Registered User
    Join Date
    Sep 2010
    Posts
    11
    Create a bool such as: lastCharWas and set it to false initially. Then when you find the first character you are looking for set it to true. Then when looking for the next character, if 'lastCharWas' is true, and the next character is whatever, increment the count. Then set 'lastCharWas' to false.

  8. #8
    Registered User
    Join Date
    Sep 2010
    Posts
    42
    Quote Originally Posted by Brokenhope View Post
    Create a bool such as: lastCharWas and set it to false initially. Then when you find the first character you are looking for set it to true. Then when looking for the next character, if 'lastCharWas' is true, and the next character is whatever, increment the count. Then set 'lastCharWas' to false.
    Thanks for the tip. I couldnt get the bool function to work so i used int set to 0 or 1. Here is my code now but its just counting the "s". Am I barking up the right tree?

    Off to find dinner. I'll check back after my belly quits complaining!
    Code:
    #include <stdio.h>
    
    
    int main(void)
    {
    	char ch;
    	int is_count = 0;
    	int lastchar = 0;
    
    	printf("Key in your word or phrase:  \n");
    	
    	while ((ch = getchar()) !='#')
    	
    	{
    		if (ch == 'i')
    			lastchar = 1;
    		
    		if (ch == 's' && lastchar == 1)
    			is_count++;
    			
    	}
    	lastchar = 0;
    	printf("\"is\" count %d\n", is_count);
    
    	getchar();
    	getchar();
    	return 0;
    }

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Every time you find an 's', (which has been preceded by an i), you need to reset a variable.
    Last edited by Adak; 09-27-2010 at 11:42 PM.

  10. #10
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198
    Quote Originally Posted by Adak View Post
    Every time you find an 's', you need to reset a variable.
    like this:

    Code:
    			is_s_count = FALSE;
    		}
    
    		is_s_count = FALSE;
    my god, I never thought this thread would last this long. Probably never broke out
    the pen & paper like I originally suggested.

    And I still don't see that 3rd if() to test if both are "i" and "s" were set. I have the
    working solution for this, but I require some thought and effort by the OP.

    Adak, can I IM you my code? I tested it and it seems to work fine. I'm not sure if it meets
    the "state machine" implementation, that may/may not be required.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Sure, you can pm me the code, if you like.

    While I like programming in C, I have little formal education in computer science, so the categories of state machines, are not right on the tip of my tongue.

    I dumped IM because it used up too many resources.

  12. #12
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198
    Quote Originally Posted by Adak View Post
    Sure, you can pm me the code, if you like.

    While I like programming in C, I have little formal education in computer science, so the categories of state machines, are not right on the tip of my tongue.

    I dumped IM because it used up too many resources.
    ok, well to me, IM and PM I thought were the same thing. Ok Sending it now.

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Try the phrase (don't ask how I think of these phrases!):
    mississippi is since I was#

    Mississippi = 2, is = 1, and it should be 3, I believe, but the program is reporting "4".

    Want to look at that.

    Yes, this is like a state machine design, rather loosely. You don't define states rigidly, however.

    A non-state design (to me), would be using strchr() to find the "is" strings.

  14. #14
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198

    Wink

    Quote Originally Posted by Adak View Post
    Try the phrase (don't ask how I think of these phrases!):
    mississippi is since I was#

    Mississippi = 2, is = 1, and it should be 3, I believe, but the program is reporting "4".

    Want to look at that.

    Yes, this is like a state machine design, rather loosely. You don't define states rigidly, however.

    A non-state design (to me), would be using strchr() to find the "is" strings.
    I just ran the program, and for input I did both Mississippi and mississippi and I got 2.

    Also, I did not implement a state machine, as that would be a silly waste of my time.

    Since you have some different results, I wonder if this is platform related? Anyway,
    below is my non-state machine solution.

    Code:
    #include <stdio.h>
    
    #define TRUE 1
    #define FALSE 0
    
    int main(void)
    {
    	char ch;
    //	char next_ch;
    	int is_i_count = FALSE;
    	int is_s_count = FALSE;
    
    	int total=0;
    	
    	printf("Key in your word or phrase:  \n");
    	
    	while ((ch = getchar()) !='#')
    	
    	{
    		if (ch == 'i')
    			is_i_count = TRUE;
    		
    		if (ch == 's')
    			is_s_count = TRUE;
    
    		if( is_i_count && is_s_count )
    		{
    			total++;
    			is_i_count = FALSE;
    			is_s_count = FALSE;
    		}
    
    		is_s_count = FALSE;
    	}
    	
    	printf("\"is\" count %d\n", total);

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    @d2rover, your while loop needs to be changed, to:

    Code:
    	while ((ch = getchar()) !='#')
    	
    	{
    		if (ch == 'i')
    			lastchar = 1;
                    else {
                           if(ch != 's')
                             lastchar = 0;
                    }
                    		
    		if (ch == 's' && lastchar == 1) {
    			is_count++;
    			lastchar = 0;
                    }
    	}
    
    Try your program with the phrase: Mississippi is since I was  //added the "is"
    (which should total 3), and you'll see the problem 
    with your code
    @Char*Pntr: Your code MAY break on the phrase "Mississippi is since I was", not on just Mississippi.

    Edit: Oh wait one! You changed it - sly devil! Try the trouble phrase, above. Do you get 3?
    Last edited by Adak; 09-28-2010 at 12:52 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Warnings about initializer order
    By CodeMonkey in forum C++ Programming
    Replies: 5
    Last Post: 06-18-2009, 07:55 PM
  2. Switching letters
    By XiReDDeViLiX in forum Windows Programming
    Replies: 4
    Last Post: 06-06-2002, 06:48 AM
  3. Character counting program
    By TankCDR in forum C++ Programming
    Replies: 5
    Last Post: 04-05-2002, 10:01 PM
  4. Counting letters in window
    By Soldier in forum C++ Programming
    Replies: 3
    Last Post: 03-29-2002, 11:34 PM
  5. Replies: 1
    Last Post: 01-06-2002, 06:28 PM