Как я могу создать std :: vector <std :: string> и затем отсортировать их? - PullRequest
31 голосов
/ 27 марта 2009

У меня есть куча строк, которые мне нужно отсортировать. Я думаю, что std :: vector был бы самым простым способом сделать это. Однако я никогда раньше не использовал векторы и поэтому хотел бы получить некоторую помощь.

Мне просто нужно отсортировать их по буквам, ничего особенного. Действительно, функция string :: compare будет работать.

После этого, как я могу просмотреть их, чтобы убедиться, что они отсортированы?

Вот что у меня есть:

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);
}

Ответы [ 7 ]

65 голосов
/ 27 марта 2009

Вы можете просто сделать

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

И это будет сортировать ваши строки. Затем просмотрите их, проверяя, в порядке ли они

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

В частности, std::string::compare нельзя использовать в качестве компаратора, потому что он не делает то, что хочет sort: вернуть true, если первый аргумент меньше второго, и вернуть false в противном случае. Если вы используете sort, как указано выше, он просто будет использовать operator<, что будет делать именно это (то есть std::string заставляет его возвращать first.compare(second) < 0).

3 голосов
/ 27 марта 2009

В чем конкретно вопрос? Кажется, все уже есть.

Однако вам, вероятно, следует использовать std::cout << *i << std::endl;

  1. i - это итератор == указатель на данные в контейнере, поэтому необходимо *
  2. c_str() является функцией std::string, а не переменной

Проблемы в вашем коде не относятся к вашему вопросу?

Несколько советов для вас:

  • std::vector также переопределяет оператор [], поэтому вы можете вместо этого сохранить итератор и использовать его как массив (итерацию от 0 до vector.size()).
  • Вместо этого вы можете использовать std::set, который автоматически сортирует при вставке (двоичное дерево), поэтому вы сохраняете дополнительную сортировку.
  • Использование функтора делает ваш вывод еще более увлекательным: copy(V.begin(), V.end(), ostream_iterator<std::string>(cout, "\n"));
2 голосов
/ 27 марта 2009

лит правильно, как всегда.

Я просто хотел указать на более общий момент - все, что можно сравнить с <можно отсортировать с помощью std :: sort. Иногда я вставляю оператор <член-функцию в структуру, просто чтобы я мог это сделать. </p>

2 голосов
/ 27 марта 2009

Для сортировки:
std::sort или std::vector< std::string>::sort(..) метод.
Чтобы проверить, отсортировано ли это:
используйте std::is_sorted для проверки сортировки - http://www.sgi.com/tech/stl/is_sorted.html
или
std::adjacent_find( v.begin(), v.end(), std::greater< std::string >() ) == v.end()

для вашего случая вы можете использовать компаратор по умолчанию

РЕДАКТИРОВАНИЕ:
std::is_sorted не является стандартной функцией stl, она определена в реализации sgi stl.
Спасибо @Brian Neal за эту заметку.

0 голосов
/ 17 марта 2018

Попробуйте использовать 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;
 }
0 голосов
/ 21 ноября 2015

Сортировка строки:

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

Проверка, отсортирован ли вектор:

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 Метод проверки отсортированного вектора: std::is_sorted(vec.begin(),vec.end())

Теперь печатаем отсортированный вектор:

   for(std::vector< std::string>::iterator i = vec.begin(); i != vec.end(); ++i)
{
    std::cout<< *i <<std::endl;
}
0 голосов
/ 27 марта 2009

Вы можете использовать std::set, который, естественно, является отсортированным контейнером.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...