web-dev-qa-db-fra.com

Comment puis-je construire un std :: vector <std :: string> et ensuite les trier?

J'ai un tas de chaînes que je dois trier. Je pense qu'un std :: vector serait le moyen le plus simple de le faire. Cependant, je n'ai jamais utilisé de vecteurs auparavant et j'aimerais donc de l'aide.

J'ai juste besoin de les trier par ordre alphanumérique, rien de spécial. En effet, la fonction string :: compare fonctionnerait.

Après cela, comment puis-je parcourir ces éléments pour vérifier qu'ils sont triés?

Voici ce que j'ai jusqu'à présent:

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

Vous pouvez juste faire 

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

Et ça va trier vos ficelles. Puis passez-les en revue pour vérifier s’ils sont en ordre

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

En particulier, std::string::compare ne peut pas être utilisé en tant que comparateur car il ne fait pas ce que sort veut qu'il fasse: Renvoie true si le premier argument est inférieur au second, et renvoie false sinon. Si vous utilisez sort comme ci-dessus, il utilisera simplement operator<, ce qui fera exactement cela (i.e std::string le fera retourner first.compare(second) < 0).

63

Quelle est la question exactement? Il semble que tout est déjà là.

Cependant, vous devriez probablement utiliser std::cout << *i << std::endl;

  1. i est un itérateur == pointeur sur les données du conteneur, donc * est nécessaire.
  2. c_str() est une fonction de std::string et non une variable

Les problèmes de votre code ne sont pas liés à votre question?

Quelques indices pour vous:

  • std::vector annule également l'opérateur [], de sorte que vous pouvez à la place enregistrer les tracas d'itérateurs et les utiliser comme un tableau (itérer de 0 à vector.size()).
  • Vous pouvez utiliser std::set à la place, qui trie automatiquement lors de l'insertion (arborescence binaire), afin de sauvegarder le tri supplémentaire.
  • Utiliser un foncteur rend votre sortie encore plus amusante: copy(V.begin(), V.end(), ostream_iterator<std::string>(cout, "\n"));
3
ypnos

litb est correct, comme toujours.

Je voulais juste souligner le point plus général - n'importe quoi qui peut être comparé avec <peut être trié avec std :: sort. Je vais parfois glisser une fonction opérateur <membre dans une structure, juste pour pouvoir le faire.

2
Mark Ransom

Essayez d'utiliser un comparateur:

 #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
Ashish Kapil

Vous pouvez utiliser un std::set, qui est naturellement un conteneur trié.

0
Joe

Tri de la chaîne:

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

Vérifier si le vecteur est trié:

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 Méthode de vérification du vecteur trié:std::is_sorted(vec.begin(),vec.end())

Nous imprimons maintenant le vecteur trié:

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