find & count string withing a string> works, but any help improving it?

this is an exam question i failed to answer properly, im trying to work it out. the code i came up with is below, it works ok, but i was hoping if anyone could help in improving it. iv read in various threads in daniweb itself about making a code run faster etc.. havent really understood much, maybe anyone can help me understand them here, with this code if possible. thanks a lot in advance :)

Code is useless at this point. Not your code, but ANY code. First, before ANYTHING ELSE, get the right algorithm. And you don't have it.
No amount of optimizing later will overcome the problems of a poor choice in the algorithm.
And this is the algorithm you should be studying: … Read More

There are WAY too many algorithms to remember even the most important one's. Because depending on what the program is doing, LOTS of them are very important.
I'm a hobbiest, and never took anything beyond the first semester of C, but I've got a FEW years of hobby experience with … Read More

Interesting. Stanford and MIT (among several others), also have computer classes/lessons on-line.
There are several other "problem/challenge" computer programming sites also:
These are the two problems I've helped with:
Codechef: http://www.codechef.com/BTCD2012/problems/DOORS
SPOJ: http://www.spoj.com/problems/TDKPRIME/
And the funniest of them all:
http://www.ioccc.org/
hilarious! ;) Park your C code sanity, at the door! Read More

THAT is the most widely used string searching algorithm, and at that link, at the bottom of the page, is a link to a C example showing it.

What's wrong with your algorithm? You are stepping through the string by merely 1 char at a time.

ONE CHAR AT A TIME

Think about it. How could that be improved?

The thing is, you need to work it through with paper and pen several times, by hand. Do YOU check for a string inside a larger string, by checking EACH AND EVERY CHAR?

Of course not!

What do YOU do? Work it through several times, S-L-O-W-L-Y, and notice the pattern that your eye and pen follow doing this. The pattern will reveal itself if you repeat it enough.

And do read up on Boyer-Moore, for all kinds of hints. You don't need to use all their tricks, but you should use some of them.

Save this code, and later, put a timer in it and compare it's time, with Boyer-Moore's program. The difference is astounding if the text being searched is large. The larger the sub-string, the quicker BM's algorithm gets.

Thinking more about your post, I'm not sure whether you wanted a more optimal program, or a simpler - clearer - program. If it's simpler and clearer, or for a small assignment/job, then I would use strstr(), (part of the string.h include file definitions), in a loop:

#include <stdio.h>
#include <string.h>
int main(void) {
int n,len;
char text[273]={"I am the eagle, I live in high country, in rocky\n"
"cathedrals that reach to the sky. I am the hawk,\n"
"and there's blood on my feathers, but time is still turning,\n"
"they soon will be dry. All those who see me, and all\n"
"who believe in me, share in the freedom I feel when I fly."};
char target[273];
char *pch=text;
printf("\nOur text is: \n%s\n\nEnter the string you want to search for: ",text);
fflush(stdout);
scanf("%[^\n]",target); //take all input up to a newline
printf("\nOur target to search for is: %s\n\n",target);
len=strlen(target);
n=0;
while(pch>(text-len)) {
pch=strstr(pch, target);
//printf("\ntext: %P pch: %P Press enter when ready\n\n",text,pch); getchar();
if(pch) {
printf("%s\n\n",pch);
++n;
}
pch+=len;
}
printf("\nTarget was found: %d times\n",n);
return 0;
}

But this program has a problem. Try searching for:
in rocky cathedrals that reach to the sky.

And it can't find it. The problem is the newline - the target doesn't have one, right after "rocky", and the text phrase, does have one.

So you'd have to search for"
in rocky
cathedrals that reach to the sky.

Which would require replacing [^\n] in the scanf(), with maybe[^~], or other char not in the target phrase. Which is probably not what you would want.

The answer might be to pre-process the text, replacing all newlines with spaces. Then do the search, remembering to use a space between words, even when the words wrap around to another line on a long target phrase. Every char is critical in these string searching programs.

I don't know if I could have coded this up during an exam, but for a clear and quick string searcher, it's hard to beat, imo.

There are WAY too many algorithms to remember even the most important one's. Because depending on what the program is doing, LOTS of them are very important.

I'm a hobbiest, and never took anything beyond the first semester of C, but I've got a FEW years of hobby experience with it, so:

I try to match the speed (complexity) of the algorithm, with the job. No sense trying to optimize a telephone directory sort by name, when it's your own personal directory, with 100 names or less. On the other hand, if it's the county/district directory, with 5 Million names - yeah, that's worth a very fast algorithm.

Fast algorithms I like:
Insertion sort - for almost sorted arrays, and all small one's (less than 1,000) say. Oddly, it's faster than anything else for sorting small and almost sorted arrays.

Except of course, for the King of Fast:
Counting sort - limited use, but BLAZING UNMATCHED speed, if it can be used. (which is rare)

Quicksort - with Insertion sort on small sub-arrays to optimize it, if it REALLY needs the best speed. Pick first + last value of each sub-array/2 for the pivot. Uses minimal amount of extra memory. You hear bad mouthing about it - well, not if you pick the pivot this way.

Merge sort - for large external data that can't all fit in memory.

Binary Search - great general purpose searcher of sorted data. Don't use it for tiny jobs, but ALL the medium and large ones get it.

strstr() - all but the biggest and most demanding string search jobs.
Boyer-Moore - for the most demanding string search jobs.

Depth First Search - uses minimal memory to do a LOT of look ahead. Kind of an odd "bottom feeder" (goes to the bottom depth and works around like a catfish). Used recursively with Alpha-Beta, it kicks ass in games like checkers, chess, etc. Closely related to Backtracking in general.

Dancing Links - too complex for my preference, but this coloring algorithm kicks ass, on several problems - including solving standard and giant Sudoku puzzles. Takes great advantage of linked lists ability to be inserted or removed, quick and easy.

Odometer - just something I coded up to work like the odometer on a car, recording miles or km traveled. I've used it several times to solve problems. Sometimes a brute force method is quick and easy, on PC's today. (Not so much for mobile phones, etc.). I used this to try and find the key for the dead pigeon message from WWII, that was in the news last Fall. No luck however, seems the message was coded using a one-time pad (and thus unbreakable).

Collision Detection - easy if you have just a few "asteroids", but when you have a lot of them, you need to optimize it - that's when it gets interesting.

That's most of one's I've used - except Dancing Links, which I have just studied. Most of the ways to optimize something is to work through it by hand (or in your imagination), and by being "lazy" about it. Some of the best stuff we keyboard, is with the delete key because we realize "hey, i don't need this big function there, if I just do something trivial over here".

I avoid:

Bubble sort like the plague. I use Substitution sort to find all possible pairs from a set of (numbers, names, whatever).

Bit fiddling: I don't work with bits enough to keep "fluent" with them. They'r wickedly fast, and sometimes beautifully done, but they're last on my optimizing list - dead last.

Linear searching: against my religion. ;)

There are zillions of algorithms out there, and Wikipedia has a bunch of the important one's that I've looked up, with just a few exceptions - even Dancing Links!

Eratosthenes was an interesting Greek - brilliant and well balanced in several sciences, he became known as "second" when he entered several math/science contests and came in second place. He was the head librarian in the famous Alexandria library, when it had the world's greatest knowledge resource.

He got the (very) last laugh it seems, since his Sieve for finding primes can be optimized easily, and runs in first place (fastest time), for all the ints you can fit into an array, without causing swapping to HD.