1

So I'm supposed to write a function that takes a vector of strings and sort it alphabetically but based on the last character of each string. For example, {“apple”, “banana”, “carrot”}, would be {“banana“, “apple“, “carrot”} because the last “a” in banana comes before the “e” in “apple” and the “t” in “carrot”.

This is my code so far:

#include <iostream>
#include <vector>
#include <string>

void SortByReverse(std::vector<std::string> &v)
{
    std::vector<int> int_v;

    for(int i = 0; i < v.size(); i++) // for loop to store ascii values of each last ch
    {
        int last_ch_index = v[i].size() - 1;
        int_v.push_back(int(v[i][last_ch_index]));
        std::sort(int_v.begin(), int_v.end()); // sort ascii value vector in ascending order
    }

    for(int u = 0; u < int_v.size(); u++) // iterate through ascii values vector and print corresponding str
    {
        for(int q = 0; q < v.size(); q++)
        {
            int last_ch_index = v[q].size() - 1;
            if(int_v[u] == int(v[q][last_ch_index]))
            {
                std::cout << v[q] << "\n";
            }
        }
    }
}

int main()
{
    std::vector<std::string> v = {"apple", "banana", "carrot"};
    SortByReverse(v);
}

which outputs my strings in the correct order but I don't know how to change the order in the vector itself. I tried doing

v[u] = v[q]

but that outputs "banana, banana, carrot" because it assigns "banana" to "apple" to when "apple" is supposed to be printed, you just get "banana" again. Surely there is a way to add on to the code I already have and fix this issue but I don't know how.

Aryan Dhar
  • 11
  • 1
  • 2
    your instructor almost certainly wanted you to use a custom comparator function. That will allow you to sort the vector itself, you just have to supply the compare function. See https://stackoverflow.com/questions/16894700/c-custom-compare-function-for-stdsort – pm100 Mar 02 '22 at 01:33
  • 1
    look at the last sort in the sample code here https://en.cppreference.com/w/cpp/algorithm/sort, the one that says 'sorted with lambda' – pm100 Mar 02 '22 at 01:35
  • 1
    Is _"sort it alphabetically but based on the last character of each string_" the criteria? Perhaps [`std::lexicographical_compare`](https://en.cppreference.com/w/cpp/algorithm/lexicographical_compare) with reverse iterators can do the trick? – Ted Lyngmo Mar 02 '22 at 01:43
  • 1
    @TedLyngmo That works very well! I would have made it much more complicated. :) – Retired Ninja Mar 02 '22 at 01:57
  • @RetiredNinja Cheers! Perhaps even using the "normal" sorting and then `std::copy_reverse` will be better. Only measuring will tell. – Ted Lyngmo Mar 02 '22 at 01:59
  • BTW, sorting **after** all the strings is more efficient than sorting after each string is input. – Thomas Matthews Mar 02 '22 at 02:04
  • A simple approach is using [std::sort](https://en.cppreference.com/w/cpp/algorithm/sort) and a lambda expressions that is simply `[](std::string a, std::string b) { return *a.rbegin() < *b.rbegin(); }`. See [std::basic_string](https://en.cppreference.com/w/cpp/string/basic_string) for the reverse iterator `.rbegin()`. Same approach will work for an array-of-strings (old way) or a `std::vector` (what the lambda shown is for) – David C. Rankin Mar 02 '22 at 02:35

1 Answers1

0

If sorting the original vector by back letter is your goal, there is much neater method:

  • std::sort(v.begin(),v.end(),[](string& lhs, string& rhs)(return <expr>;)); will sort the std::string vector by the <expr> criteria. make <expr> expression return true or false based on the back letter.
  • std::string has member function back() which has access to the back element, which is last char.
  • As @paddy pointed out, if you wish to make stable program, make <expr> able to handle empty string & error check.
  • As your program seems to be a homework, you figure out where to put it.
K.R.Park
  • 1,015
  • 1
  • 4
  • 18
  • It should be mentioned that a well-behaved predicate would also handle empty strings without crashing or invoking undefined behavior. It's also unclear from the question what logic applies for tie-breaking, if at all (_e.g._ two words with same last character). – paddy Mar 02 '22 at 01:56
  • @paddy Right. I will add it! – K.R.Park Mar 02 '22 at 01:59