Reverse String

/*
Reverse the words in a string.

Write a program to reverse the words in a string. Punctuation can be ignored.
Two scenarios: you can use builtins, and you can't.
*/


// built in
vector<string> tokenize(const string &fullstring)
{
    vector<string> result;
    stringstream ss(fullstring);
    string temp;

    while (getline(ss, temp, ' ')) {
        result.push_back(temp);
    }

    return result;
}

string reverse_str(string &in)
{
    vector<string> tokens = tokenize(in);
    string final_str;
    final_str.reserve(in.size());

    for (int i = 0; i < tokens.size(); i++) {
        reverse(tokens.at(i).begin(), tokens.at(i).end());
        final_str += tokens.at(i) + ' ';
    }
    final_str.pop_back();
    return final_str;
}


// self - with inbuilt vector
template<typename T>
void my_swap(T &a, T &b)
{
    T temp = b;
    b = a;
    a = temp;
}

void my_reverse(string &in) 
{
    int start = 0, end = in.size() - 1;
    while (start < end) {
        my_swap(in[start], in[end]);
        start++; end--;
    }
}

string reverse_str2(string &in)
{
    vector<string> tokens = tokenize(in);
    string final_str;
    final_str.reserve(in.size());

    for (int i = 0; i < tokens.size(); i++) {
        my_reverse(tokens.at(i));
        final_str += tokens.at(i) + ' ';
    }
    final_str.pop_back();
    return final_str;
}


// self - now without absolutely any built ins
string* tokenize2(const string &fullstring, const int num_words)
{
    string* result = new string[num_words + 1];
    stringstream ss(fullstring);
    string temp;

    int count = 0;
    while (getline(ss, temp, ' ') && count < num_words) {
        result[count++] = temp;
    }

    result[count] = "\0";
    return result;
}


/*
The idea is to treat each word as a unit.
Just like we can reverse a word, reversing
a group of words is just like doing the same
thing but on high level.
*/
string reverse_str3(string &in, const int num_words)
{
    string *tokens = tokenize2(in, num_words);
    string final_str;
    final_str.reserve(in.size());

    int counter = 0;
    while (tokens[counter] != "\0") {
        my_reverse(tokens[counter]);
        final_str += tokens[counter++] + ' ';
    }
    final_str.pop_back();
    return final_str;
}

// self - now without any built ins and in place
void reverse_str4_rec(string &in, int &it_st, int &it_end)
{
    int it_str_cp = it_st;
    int iter_start2 = 0;
    int iter_end2 = 0;

    while (in[it_st++] != ' ')
        iter_start2++;
    while (in[it_end--] != ' ')
        iter_end2++;

    string *tmp_start = &in.substr(it_str_cp, iter_start2);
    string *tmp_end = &in.substr(it_end + 2, iter_end2);
    my_reverse(*(tmp_start));
    my_reverse(*(tmp_end));

    in.replace(it_end + 2, iter_end2, *tmp_start);
    in.replace(it_str_cp, iter_start2, *tmp_end);

    if (tmp_end->size() > tmp_start->size()) {
        while (in[it_st++] != ' ');
        while (in[it_end--] != ' ');
    }
    else {
        while (in[it_st--] != ' ');
        while (in[it_end++] != ' ');
    }
}

void reverse_str4(string &in)
{
    int iter_start = 0;
    int iter_end = in.size();

    while (iter_start < iter_end) {
        reverse_str4_rec(in, iter_start, iter_end);
    }
}


int main()
{
    string one = "wow look at all these cool words";
    cout << reverse_str(one) << endl;
    cout << reverse_str2(one) << endl;
    cout << reverse_str3(one, 7) << endl;

    // inplace
    reverse_str4(one);
    cout << one << endl;
}

Last updated