0

I have this following code where there is a vector of strings. Each string is an integer. I want to sort this in a descending order. The regular sort function did not solve my problem. Can someone point out how to do this? I want the output as 345366,38239,029323. I want the leading zero in 029323 as well.

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

using namespace std;


int main() {
    vector<string> v = {"345366", "029323", "38239"};
    vector<int> temp(v.size());
    for (int idx = 0; idx < v.size(); idx++)
        temp[idx] = stoi(v[idx]);
    sort(temp.begin(), temp.end()));
    cout<<temp[0]<<" "<<temp[1]<<" "<<temp[2];

    return 0;
}
hago
  • 315
  • 2
  • 9
  • You need to write a comparison function that compares two strings and outputs which one should go first. – David Schwartz Dec 27 '20 at 01:51
  • @cigien Ok, then they have to write a special function to do that, preferably passed as a lambda calculus to the `sort()` function. – πάντα ῥεῖ Dec 27 '20 at 01:56
  • @πάνταῥεῖ, sorry but I tried what you suggested. I sorted it normally and tried printing the vector using rbegin() and rend(). This is not sorting the vector as I expected. – hago Dec 27 '20 at 01:57
  • I am not getting that special function right. – hago Dec 27 '20 at 01:58
  • _@hago_ As mentioned, your case is a bit more special, you'll need to write your own sorting calculus as @cigien menitoned. You'll need to take the number of digits into account when sorting (longest to shortest). – πάντα ῥεῖ Dec 27 '20 at 01:59
  • As mentioned, you need to write code so that you can compare "12" and "03" correctly, for example. Are your strings going to be long, or are they small numbers that fit in an `int`? – cigien Dec 27 '20 at 01:59
  • I presume long. But if it works for int, I will ok for now.. – hago Dec 27 '20 at 02:00
  • Why are you presuming anything? It's your question, and you're the one who needs to decide precisely what problem you want to solve. – cigien Dec 27 '20 at 02:01
  • Well, this is part of a coding challenge I am trying to understand. I don't have the full question else would have known the constraints. My apologies. – hago Dec 27 '20 at 02:02
  • Well, in that case, it sounds like you can solve whichever problem you want to. Just try and be precise in the question what that is. – cigien Dec 27 '20 at 02:04

1 Answers1

4

You can use a comparator function like this:

vector<string> v = {"345366", "029323", "38239"};
std::sort(v.begin(), v.end(), [](const std::string &s1, const std::string &s2) -> bool {
    return std::stoi(s1) > std::stoi(s2); 
});
for(auto i : v)
    cout << i << endl;

Check this std::stoi() reference.

Edit: From the comments, it seems std::stoi() is much better than std::atoi(). For converting C++ strings, use std::stoi(). For C strings, std::atoi() will silently fail without generating any error if the string is not convertible to int, whereas std::stoi() will generate an exception, thus is a safer choice as well.

cout << std::atoi("abc") << endl; // runs smoothly
cout << std::stoi("abc") << endl; // creates an 'uncaught exception of type std::invalid_argument: stoi'

However, the results will be the same in this case (will extract the prefix integer part and exit, in case of std::stoi(), if the string doesn't begin with integers, it will create an exception):

cout << std::atoi("999abc12") << endl; // prints 999
cout << std::stoi("999abc12") << endl; // prints 999
cout << std::stoi("abcdef12") << endl; // generates exception

Also see this answer.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Jarvis
  • 8,494
  • 3
  • 27
  • 58
  • @hago if the issue is resolved, please mark the answer as accepted to close it. – Jarvis Dec 27 '20 at 02:06
  • 1
    I think I accepted the answer. Anything else should I do here? – hago Dec 27 '20 at 02:07
  • I would suggest taking the arguments to the lambda by `const&`, instead of copying them. – cigien Dec 27 '20 at 02:08
  • That will do, thanks. Do checkout the documentation on lambdas in c++ as well. @hago – Jarvis Dec 27 '20 at 02:08
  • 1
    I did leave a comment :) Thanks for editing the answer, it's much better now. btw, in general it's not really worthwhile to leave comments asking why users downvoted. Those who don't want to say, won't say, and those who will are likely to have left constructive feedback already. – cigien Dec 27 '20 at 02:16
  • Consider using [`std::stoi()`](https://en.cppreference.com/w/cpp/string/basic_string/stol) rather than [`std::atoi()`](https://en.cppreference.com/w/cpp/string/byte/atoi). – Remy Lebeau Dec 27 '20 at 02:19
  • @Jarvis `std::stoi()` is defined in ``, not `` – Remy Lebeau Dec 27 '20 at 02:26
  • Forgot to remove that, I added it before for `atoi`. Thanks. Added some reasoning from my side as well, if you have any of your own, please let me know. @RemyLebeau – Jarvis Dec 27 '20 at 02:27