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

1. ## 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. 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. Originally Posted by d2rover
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.

4. 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. Originally Posted by nonoob
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. How can I tell the code if ch == i to advance ch to the next letter and check for "s"?

7. 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. Originally Posted by Brokenhope
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. Every time you find an 's', (which has been preceded by an i), you need to reset a variable.

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. 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.

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. 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.

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. @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