Can someone explain what is happening in the bleep C++ for loop

I was working through Bleep in the C++ course in the section on references-pointers found here:
https://www.codecademy.com/courses/learn-c-plus-plus/projects/cpp-bleep

There are a couple instances in the solution, inside nested loops, that have somethings like this:

if ( text [ i + j ] == word [ j ] )

In this instance ’ i ’ is from the first for loop and the ’ j ’ is the second nested for loop. I’m confused about which values are being passed and what we’re comparing. I assume we’re trying to compare letter values to one another? But in that case why are we adding ’ i + j '? Why wouldn’t it just be text[ i ] == word [ j ]? I’ve written it out on paper and am still confused about how it works. At least numerically it would seem that no matter if the letters match or not, during the first loop of ’ j ’ that i = 0 so no matter what ’ i + j ’ will always == [ j ]. But if instead we’re looking at what letter values in the portions held at text[i] and word[i] what is happening with text[i + j]? Hopefully this confusion makes sense and someone can explain what is happening. Thank you!

that’s straight up wrong and is reading outside the string

It’s listed as the solution for the problem though. When I remove the ‘+ j’ it breaks the code so it doesn’t function properly. When I add it back it works again.

not sure what your point is
if you mean that it should be that way because some form of authority put it there, then, i explained what the problem is, and that is observable and easily reasoned about. consider the max value of i+j and consider the maximum valid index, i+j is larger than that, so that’s outside. and it is observable by printing out the size and the index used

as for what SHOULD be done, well, what would you do with pen and paper? having code and not knowing what it does is a bit backwards, normally what you do is to decide what should happen and then describe that in code, and because this (the task of censoring a word) is something you can trivially do with pen and paper, you already have an observable reference for what should happen there.

so you would consider where the values i and j come from, and what the program is supposed to look at, and then you can consider how those two relate to one another and then formulate a correct version. or, use any strategy that you’d come up with, how you’d do it manually is often the first thing to consider, by just being human you already have the answer, it’s something we’d do without conscious thought

Thank you for your reply ionatan. Yes, i trusted (the “authority”) whoever added the “solution” to be correct. When you’re learning new concepts what is observable and easily reasoned about isn’t always so clear. I don’t believe it’s backwards, no. I’m trying to better understand how this solution works so that when faced with something similar I’ll have a better idea of how to approach applying the concept to another problem. That’s why I wrote the question. When trying to solve problems in your code don’t you search for solutions and check them against your ideas as your learning new concepts? I did write it out manually but I struggle applying pseudo code in syntactics as I haven’t spent that long in the programming word.

Since you seem to now be taking the authoritative role here I’ll ask you some more questions in regard to you reply. Why is it wrong to move outside the the scope of the string if the you the code still returns the result you want? What are possible problems that could arise? Why is it not throwing errors? Is there a way to better (or what would be your way) to write the for loop so that it doesn’t go outside of the scope of the string but stills cycles through comparing the text[ i ] to word[ j ]?

1 Like

If a string is ten characters long and you read at position 15, do you expect to find something reasonable there?
It doesn’t give off errors because cpp does as you say. You said to read there, it reads there. The os might complain if you read somewhere outside the program itself.
To fix it you’d say the right thing instead of the wrong thing. That’s not very much about writing the loop differently, it’s about considering what should at all happen.

Stick to the strategies you come up with yourself. Relentlessly. If you’re not, then what are you following? No don’t even bother trying to find other strategies. Work on describing what you came up with instead.

You might want to use a different language for learning. C++ is fine to learn with if you can be really disciplined about it, making sure to stay in control and willing to observe everything and so on. I’d suggest C# or Go, anything with a compiler that is quick to complain and doesn’t let you get away with things, there are many such languages. Rust comes to mind too, that might actually give you a hard time though as a result of being really picky about what it allows to be compiled in ways that are non-obvious to the beginner. C++ is fine too, but you’ll run into a lot of cases where it doesn’t help you out in the slightest and simply does as you say.

1 Like

I hate to necro a post, but I googled this for help as well and found myself here. So here is my theory for anyone who googled this problem and found themselves VERY unsatisfied with the moderator’s non-answer:

if (text[i+j] == word[j])
I was also quite confused by this line. however, the square brackets make it not a numerical value. Rather it is looking for the character in that number place as you theorized; however, if you just did i compared to j it would check i up to 8 characters, see there are no matches, and end the loop. The purpose of adding i + j makes so that when the second loop reiterates and checks 8 characters again, it checks it one space forward in the text string, checking 8 character bunches, and only returning an asterisk chain if every single letter matches when it iterates through the 8 character bunches at different spots in the character string.
The reason you can’t just use if (text[i] == word[j]) is because by this logic, it will check the 1 letter represented by i against all 8 letters of broccoli, (and if it matches) add one to match, but this makes it so that match is not equal to the character length of broccoli, so it never sees the if statement that calls the asterisk() function as true. In the original setting of the solution, the only purpose of i is to set the checking sequence in a new place instead of checking the beginning 8 characters over and over.
It seems like there would be much easier ways to do this, but I certainly would not say it is “straight up wrong”.

you could rewrite this program so that if(text[i] == word[j]) works, but in the solution’s current structure, it needs the +j to operate.

I hope this makes sense. I reread over this code 70 times trying to figure out what that line meant, because it clearly works, but the logic is hard to follow.

2 Likes

Wow, I’m glad i stumbled upon this, even though it’s been several months later since I asked the same question to hear the same bs response lol. Proof: https://stackoverflow.com/questions/62604536/visualstudios-throws-exception-while-codeblocks-does-not-c

I will re-read your response again later sner and try to make sense of it as I am currently in a rush to head out atm, but need to get this response out. Also, this actually does give error in VS but not in codeblocks. Also, ionatan, though being very ignorant in there response, is right on how you come up with your own idea on how to solve this. I’ve came up with about 2 different ways to solve this bleep challenge as it’s been one of the most interesting challenge to undergo. It’s really fun though.

1 Like

This is so much more helpful than what I had been finding.

From what I’ve read since I read your post, it sounds like references and pointers can have indexes like arrays do. I feel like that’s kind of what’s happening here?

Like you I find myself reading through the original solution (and your post) over and over and the light shines a little brighter with each pass ha ha! :bulb:

1 Like

Let me try to explain what I understand from this.
In this section of the code there are two loops, one inside another. I will call them “outer loop” and “inner loop”.

for (int i = 0; i < text.size(); ++i) {
int match = 0;
for (int j = 0; j < word.size(); ++j) {
if (text[i+j] == word[j]) {
++match;
}
}
if (match == word.size()) {
asterisk(word, text, i);
}
}

The outer loop refers to string text, while the inner loop refers to string word.
The string text has 300 characters (300 positions, from 0 to 299) and the outer loop will iterate all of them, one at a time. When it receives the first position, the letter “I”, it passes the position i = 0 to the inner loop.
Once inside the inner loop, i becomes fixed, because now the inner loop will iterate through the string word that has 8 positions, comparing i to every j of the string word. So because i is now fixed, text[i+j] == word[j] means that the comparison is as follows:

0+0 == 0 → I == b (false - no match)
0+1 == 1 → _ == r (false - no match)
0+2 == 2 → s == o (false - no match)

0 + 7 == 7 → i == i (true - match)

match != word.size()

Then the outer loop goes to the second position (i = 1), the space, and the process is repeated. When it gets to the position i = 16, the first letter of the word “broccoli” in the text, the process goes like this:

16+0 == 0 → b == b (true - match)
16+1 == 1 → r == r (true - match)
16+2 == 2 → o == o (true - match)

16 + 7 == 7 → i == i (true - match)

match == word.size()

Now if we had just
text[i] == word[j]
then the process would go like this
16 == 0 → b == b (true - match)
16 == 1 → b == r (false - no match)
16 == 2 → b == o (false - no match)

16 == 7 → b == i (false - no match)

match != word.size()

I hope this helps.

1 Like