3
\$\begingroup\$

Same exact story as Verbose Word/Phrase Reverse in Node.js, but in C++.

If you don't want to follow the link:

The assignment is to:

  1. If input is a word, reverse the word. (e.g. "hello" becomes "olleh")

  2. If input is a phrase, reverse the order of the phrase but not the actual words. (e.g. "united states of america" becomes "america of states united")

The other restriction is I am only allowed to use the C++ equivalent of Java String's length, substring, charAt, concatenation and indexOf methods.

Code:

#include <iostream>

std::string ReverseWord(const std::string& word) {
    std::string reverse;
    for (unsigned long i = word.length() - 1; i <= word.length(); --i) reverse += word[i];
    return reverse;
}

std::string ReversePhrase(const std::string& phrase) {
    unsigned long last_space = phrase.length();
    std::string out;
    for (unsigned long i = phrase.length() - 1; i <= phrase.length(); --i) {
        if (phrase[i] == ' ') {
            out += phrase.substr(i + 1, last_space - i - 1) + " ";
            last_space = i;
        }
    }

    out += phrase.substr(0, last_space);
    return out;
}

int pa12() {
    std::string in;
    std::cout << "Enter a word or phrase: ";
    getline(std::cin, in);

    if (std::find(in.begin(), in.end(), ' ') == in.end()) {
        std::cout << "The reversed word is: " << ReverseWord(in) << std::endl;
    } else {
        std::cout << "The reversed phrase is: " << ReversePhrase(in) << std::endl;
    }

    return 0;
}
\$\endgroup\$
  • \$\begingroup\$ Just out of curiosity, how would dashes (like in for-loop) and slashes (like in and/or) be handled? \$\endgroup\$ – T145 Sep 23 '17 at 7:58
  • \$\begingroup\$ It would be treated as another letter, which is intended behavior. \$\endgroup\$ – Zach Hilman Sep 23 '17 at 12:21
2
\$\begingroup\$

Prefer to use iterators to iterate through data structures

Look how nice your ReverseWord function becomes when you use the provided rbegin() and rend():

std::string ReverseWord(const std::string& word) {
  return std::string(word.rbegin(), word.rend());
}

Use algorithms when possible

Similarly, your finding of the spaces can be done with a simple string::find() instead.

Apart from that, the code looks reasonable. However...

High level

This is an algorithm that's traditionally implemented as an in-place transformation on a string_view (or array of chars, pre-c++17)

You definitely would want to revisit this and tackle the problem from that angle instead.

It's a bit of a "trick" question, as there is a very simple algorithm to do it, but it's not exactly obvious at first glance. That's why the question asks to reverse a word first. Once you figured out how to reverse a word in-place, the solution to "reverse the words of a phrase" becomes a bit more clear.

\$\endgroup\$
  • \$\begingroup\$ Look at the task again: The other restriction … \$\endgroup\$ – Roland Illig Sep 22 '17 at 4:36
  • \$\begingroup\$ @RolandIllig, I don't see much reason to use C++ instead of Java then (I'm not Frank). Also the code needs to include <string>. \$\endgroup\$ – Incomputable Sep 22 '17 at 5:59
  • \$\begingroup\$ The task is an exercise in low-level character handling. Sure, almost all languages provide more powerful concepts nowadays, so this task is more for fun than for real use. \$\endgroup\$ – Roland Illig Sep 22 '17 at 18:05
  • \$\begingroup\$ Yeah, this happens to be my 10th or so assignment in C++, and while I knew how to use reverse iterators, I didn't know the specifics of substr, which I learned in this assignment. \$\endgroup\$ – Zach Hilman Sep 23 '17 at 12:22
0
\$\begingroup\$

To reverse a word:

#include <iostream>
#include <string>
int(main)
{
using namspace std;
string word = "hello";
char temp;
int x, y;
for (x = 0, y = word.size() - 1; x < y; --y, ++x)
{
temp = word[y];
word[y] = word[x];
word[x] = temp;
}
cout << word << endl;
return 0;
}

Note: It is common to use such syntax and easy to read with much simpler coding which guarantees the loop to stop once it reaches the middle element of the string. Though i have read many reverse coding that cause some implementations to set back the order of the string elements right back or keep executing more than the loop test yields. This syntax makes sure that the loop will stop once the bool of the test becomes false.

\$\endgroup\$
  • \$\begingroup\$ This doesn't appear to be a review of the code in the question. It appears to be a reimplementation of one part of it. Can you comment on why you think this is a better way than what's in the question? \$\endgroup\$ – user1118321 Sep 27 '17 at 5:38
  • \$\begingroup\$ It is common to use such syntax and easy to read with much simpler coding which guarantees the loop to stop once it reaches the middle element of the string. Though i have read many reverse coding that cause some implementations to set back the order of the string elements right back or keep executing more than the loop test yields. This syntax makes sure that the loop will stop once the bool of the test becomes false. \$\endgroup\$ – Smk Quighty Sep 27 '17 at 5:53
  • \$\begingroup\$ Great explanation! You should edit that into your answer as comments are periodically removed. \$\endgroup\$ – user1118321 Sep 27 '17 at 16:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.