Click to See Complete Forum and Search --> : I just don't get it


357mag
06-06-2007, 01:05 AM
I'm working on this cool program that replaces a word in a string with another word. It's out of one of my C++ books. Here is the code:

int main()
{
string text = "A rose is a rose is a rose.";
string word = "rose";
string replacement = "horse";
int start = 0;

start = text.find(word);

while (start != string::npos)
{
text.replace(start, word.length(), replacement);
start = text.find(word, start + replacement.length());
}

cout << text << endl;

return 0;
}

The line:

start = text.find(word)

I know basically what that does. It justs finds the starting index of the word and assigns it to the start variable.

The line:

while (start != string::npos)

I guess what that does is tell the compiler to keep going through the string until the word "rose" is no longer found. Okay.

The line:

text.replace(start, word.length(), replacement)

This tells the compiler to remove 4 characters("rose") starting at index position 2(where "rose" is first found) and replace it with "horse." Okay.

But I do not understand this line at all:

start = text.find(word, start + replacement.length())

I did a test and I commented out some lines of code and ran the program and the compiler said the next index position of word "rose" was found at index position 12. Okay. So if the compiler has already moved to index position 12 and has already found the next occurrence of "rose" at index position 12, what is the purpose of start + replacement.length()?

I guess it has something to do with the likelyhood that the replacement word is a different length than the original word. I get that. But if text.find(word) has already returned the new index position of the next occurrence of "rose", what happens immediately after that?

I just don't understand that line no matter how I try. I'm close, but I need some help.

357mag
06-06-2007, 01:43 AM
I mean if text.find(word,...) has already returned the index position 12, which is where the next occurrence of "rose" is found, how does the start + replacement.length() fit in to all of this?

Does the compiler go "Okay, I found the next occurrence of "rose" at index position 12, now I will take the value in start(which is 12 now I guess) and add to that the number of characters in "horse" which is 5 and then 12 + 5 equals 17. I don't get it.

Perhaps it might help if I knew exactly what was going on with just the beginning few words of this:

start = text.find(word,...)

Does the find function find the next occurrence of "rose" which is found at index position 12, or does it stay at the first occurrence of "rose" which was found at index position 2?

Peter_APIIT
06-06-2007, 02:32 AM
I have no idea.

357mag
06-06-2007, 02:50 AM
Well I did a little experimenting and I removed the start + replacement.length() so now it looks like this:

while (start != string::npos)
{
text.replace(start, word.length(), replacement);
start = text.find(word);

}

And then I ran the program and it worked fine. It output:

A horse is a horse is a horse

Beats me. Maybe Ivor Horton made it unnecessarily complicated?

Viorel
06-06-2007, 03:56 AM
I think the reason for original code is skipping of portions of string which were already analyzed and replaced. This does not seem to be necessary for your particular example, but is important if you replace "rose" with "prose", or "rose" with the same "rose", and for other cases. Changed code will loop infinitely.

I hope this makes sense.

Danny
06-06-2007, 07:02 AM
In short, it makes start skip the recently process portion of the string, so that the next an algorithm uses start, it will skip the characters that have just been inserted/replaced.

357mag
06-07-2007, 01:43 AM
So the line:

start = text.find(word)

will tell the compiler to move to the next position of the next occurrence of the word "rose". Correct? Then those other positions would be index position 12 and finally index position 22. If I'm understanding you correctly. I wish Ivor Horton would have explained this a little more.

Danny
06-07-2007, 01:57 AM
I'll save my opinion on Ivor Horton's writing for a different occasion...
Anyway, start = text.find(word)
does the following: it finds the first letter of word in string, and assigns that letter's position to start.
One more thing: it's not a compiler's job to invoke algorithms and member functions; the calculation takes place at runtime. The compiler only generates object code for the specific source file it compiles.

357mag
06-10-2007, 03:17 AM
But what I want to be clear on is that:

start = text.find(word)

keeps finding the "next" position of the word "rose". Correct? So the text.find () function keeps moving forward always to find the next occurrence of the word you are looking for and always assigns the "next" position to the start variable.

That must be how it works.

Danny
06-10-2007, 04:28 AM
It works between you reassign a new value to start before each call to find. In other words, find() doesn't start to look for word from the beginning of the string, it starts from the current value of start, which is updated in every loop iteration. One more thing: start = text.find(word) is wrong. You need to include a range in the find() call to ensure that find() skips the previously found values.

357mag
06-10-2007, 11:40 PM
Well I removed the start + replacement.length() and the code still worked fine. It functioned just fine without that start + replacement.length() in there. I mentioned that in one of my earlier posts.

357mag
06-10-2007, 11:55 PM
I just tried it again with just the text.find(word) and again it works fine. One thing I'm not too clear on is what pushes the compiler to the "next" position of the word you are looking for? When you first write:

int start = text.find(word)

That would assign the position of the very first occurrence of the word "rose" to the start variable. In my particular example I believe that would be index position 2. The next index position that "rose" is found is at index position 12.
But what pushes the compiler along to get there? Is it the while statement:

while (start != string::npos)

It seems to me that something in the code would have to tell the compiler to move forward to find the next occurrence of the word "rose". And I'm not clear on what line really tells the compiler to do that.

Danny
06-11-2007, 02:27 AM
The thing is: every replace call erases the previously found 'word' so the next find call will point at the next occurrence of word -- the previous one is already replaced with a another text.