44

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);
}
samoz
  • 56,849
  • 55
  • 141
  • 195

7 Answers7

79

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).

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 8
    Just for fun (and untested): Checking that the vector is sorted could be simplified to std::adjacent_find(names.begin(), names.end(), std::greater()) == names.end() – Éric Malenfant Mar 27 '09 at 02:30
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"));
John_West
  • 2,239
  • 4
  • 24
  • 44
ypnos
  • 50,202
  • 14
  • 95
  • 141
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.

Martin Quinson
  • 1,347
  • 8
  • 16
bayda
  • 13,365
  • 8
  • 39
  • 48
  • 1
    You shouldn't rely on that sgi site for info on the STL. It predates the standard. is_sorted isn't standard. – Brian Neal Mar 27 '09 at 00:37
  • 2
    correct me if i'm wrong : is_sorted is added in c++11 http://en.cppreference.com/w/cpp/algorithm/is_sorted – abe312 Jan 24 '16 at 09:54
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.

Community
  • 1
  • 1
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
2

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

John_West
  • 2,239
  • 4
  • 24
  • 44
Joe
  • 41,484
  • 20
  • 104
  • 125
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;
}
abe312
  • 2,547
  • 25
  • 16
0

Try using comaprator:

 #include <cmath>
 #include <cstdio>
 #include <vector>
 #include <iostream>
 #include <algorithm>
 using namespace std;

//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(),myfunction);

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

return 0;
 }
Ashish Kapil
  • 102
  • 8