45

I have a bunch of strings that I need to sort. I think a std::vector would be the easiest way to do this. However, I've never used vectors before and so would like some help.

I just need to sort them alphanumerically, nothing special. Indeed, the string::compare function would work.

After that, how can I iterate through them to verify that they're sorted?

Here's what I have so far:

std::sort(data.begin(), data.end(), std::string::compare);

for(std::vector<std::string>::iterator i = data.begin(); i != data.end(); ++i)
{
    printf("%s\n", i.c_str);
}
1

7 Answers 7

80

You can just do

std::sort(data.begin(), data.end());

And it will sort your strings. Then go through them checking whether they are in order

if(names.empty())
    return true; // empty vector sorted correctly
for(std::vector<std::string>::iterator i=names.begin(), j=i+1; 
        j != names.end(); 
        ++i, ++j)
    if(*i > *j)
        return false;
return true; // sort verified

In particular, std::string::compare couldn't be used as a comparator, because it doesn't do what sort wants it to do: Return true if the first argument is less than the second, and return false otherwise. If you use sort like above, it will just use operator<, which will do exactly that (i.e std::string makes it return first.compare(second) < 0).

Sign up to request clarification or add additional context in comments.

3 Comments

Just for fun (and untested): Checking that the vector is sorted could be simplified to std::adjacent_find(names.begin(), names.end(), std::greater<std::string>()) == names.end()
This doesn't sort correctly according to case. Uppercase characters will be sorted before lowercase. I.e., it's basically useless.
@James according to the problem statement "std::string::compare would work".
5

What is the question exactly? It seems everything is already there.

However, you should probably use std::cout << *i << std::endl;

  1. i is an iterator == pointer to the data in the container, so * is needed
  2. c_str() is a function of std::string and not a variable

The problems in your code do not relate to your question?

Some hints for you:

  • std::vector also overrides [] operator, so you can instead save the iterator hassle and use it like an array (iterate from 0 to vector.size()).
  • You could use std::set instead, which has automatically sorting on insertion (binary tree), so you save the extra sorting.
  • Using a functor makes your output even more fun: copy(V.begin(), V.end(), ostream_iterator<std::string>(cout, "\n"));

Comments

2

litb is correct, as always.

I just wanted to point out the more general point - anything that can be compared with < can be sorted with std::sort. I'll sometimes sneak an operator< member function into a struct, just so I can do this.

Comments

2

For sort use:
std::sort or std::vector< std::string>::sort(..) method.
To check if it is sorted:
use std::is_sorted for check is sorted - http://www.sgi.com/tech/stl/is_sorted.html
or
std::adjacent_find( v.begin(), v.end(), std::greater< std::string >() ) == v.end()

for your case you could use default comparator

EDITED:
std::is_sorted is not standard stl function, it defined in sgi stl implementation.
Thanks @Brian Neal for this note.

2 Comments

You shouldn't rely on that sgi site for info on the STL. It predates the standard. is_sorted isn't standard.
correct me if i'm wrong : is_sorted is added in c++11 en.cppreference.com/w/cpp/algorithm/is_sorted
1

Sorting the string:

using namespace std; // to avoid using std everywhere 
std::sort(data.begin(), data.end()); // this will sort the strings

Checking whether vector is sorted:

if(vec.empty())
    return true; // empty vector is sorted correctly
for(std::vector< std::string>::iterator i=vec.begin(), j=i+1; j != vec.end(); ++i, ++j)
    if(*i > *j)  return false;
return true; // sort verified

C++11 Method to check sorted vector: std::is_sorted(vec.begin(),vec.end())

Now printing the sorted vector:

   for(std::vector< std::string>::iterator i = vec.begin(); i != vec.end(); ++i)
{
    std::cout<< *i <<std::endl;
}

5 Comments

I've checked on codeblocks and ideone and this WORKS just fine.
Since C++11, checking if the vector is sorted is simply std::is_sorted(vec.begin(),vec.end())
You shouldn't rely on that sgi site for info on the STL. It predates the standard. is_sorted isn't standard
is_sorted isn't standard
AFAIK, is_sorted was added in C++11
1

You could use a std::set, which is naturally a sorted container.

2 Comments

Limitation: std::set doesn't support random access like std::vector.
std::set doesn't accept duplicates.
0

Try using comparer:

// Comparing function only sorts if string size is equal and keeps the larger integgers at last.
bool myFunction (string i, string j) 
{ 
   int n = i.length();
   int m = j.length();

   if (n == m)
       return i < j;
   return n < m;   
}


int main()
{
    int n;
    cin >> n;
    vector <string> arr(n);

    for (int i = 0; i < n; i++)
        cin >> arr[i];

    sort(arr.begin(), arr.end(), mFfunction);

    for (int i = 0; i < n; i++)
        cout << arr[i] << endl;

    return 0;
 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.