Just for variety's sake, let's try a reverse iterator to take away some of the drudge work of indexes. Then we'll account for spaces at the end of the string with a simple boolean flag found_nonspace
. It starts out false.
Each time through the loop we examine the current character. If the flag is false, and it's a space, we use continue
to move onto the next iteration. In this manner we can skip all trailing whitespaces.
As soon as it hits something that is not a space, we flip the flag to true and add that character to s1
.
If the flag is true, then we've been going through the last word. If that's the case and we hit a space, then we break
and the loop is done. We've got the entire last word in s1
.
Finally, there's no need to check anything. At this point we know by process of elimination that we're in the last word, and it's still going on, so we add the current character to s1
.
Of course, s1
will be the last word backwards, but as we're only accumulating it to return its length, that's irrelevant.
#include <iostream>
#include <string>
int lengthOfLastWord(string const& s);
int main() {
std::string s;
std::getline(std::cin, s);
std::cout << lengthOfLastWord(s) << std::endl;
}
int lengthOfLastWord(string const& s) {
bool found_nonspace = false;
std::string s1;
for (auto ch = s.rbegin(); ch != s.rend(); ch++) {
if (!found_nonspace && std::isspace(*ch)) {
continue;
}
else if (!found_nonspace) {
found_nonspace = true;
s1.push_back(*ch);
}
else if (found_nonspace && std::isspace(*ch)) {
break;
}
else {
s1.push_back(*ch);
}
}
return s1.length();
}
In fact, if we really don't need to get the last word, but just its length, we needn't worry about s1
at all, and could just increment a length variable and then return it.
#include <iostream>
#include <string>
int lengthOfLastWord(string const& s);
int main() {
std::string s;
std::getline(std::cin, s);
std::cout << lengthOfLastWord(s) << std::endl;
}
int lengthOfLastWord(string const& s) {
bool found_nonspace = false;
int len = 0;
for (auto ch = s.rbegin(); ch != s.rend(); ch++) {
if (!found_nonspace && std::isspace(*ch)) {
continue;
}
else if (!found_nonspace) {
found_nonspace = true;
len += 1;
}
else if (found_nonspace && std::isspace(*ch)) {
break;
}
else {
len += 1;
}
}
return len;
}
Let's really exercise iterators
We can actually make this a lot more terse, just by declaring our reverse_iterator
outside of our loops. We'll use two loops. The first will reverse advance (from the end) the iterator through any spaces. This loop doesn't need a body.
Second, we'll basically do the same, but advance over any non-space characters, incrementing len
as we go. Then we'll return len
.
Also: we'll definitely want to check that we aren't trying to iterate too far by checking for ch != 2.rend()
.
int lengthOfLastWord(string const& s) {
std::string::reverse_iterator ch = s.rbegin();
int len = 0;
for (; ch != s.rend() && std::isspace(*ch); ch++);
for (; ch != s.rend() && !std::isspace(*ch); ch++, len++);
return len;
}