Does anyone know how to insert names in alphabetical order into a c++ vector?

Asked

Viewed 3,071 times

6

I made this code but it doesn’t work right, it inserts in alphabetical order backwards.

void inserirNomeNaLista(vector<string> &lista)
{
    vector<string>::iterator itr;
    string nome;
    cout << "Digite o nome para ser inserido na lista: ";
    cin >> nome;

    if (lista.size() == 0)
    {
        lista.push_back(nome);
    }
    else
    {
        for (itr = lista.begin(); itr != lista.end(); itr++)
        {
            if (*itr > nome)
            {
                lista.insert(itr, nome);
            }
            break;
        }
    }
}
  • 3

    Are you sure he’s always inserting backwards? His break is outside the block of if (*itr > nome) (instead of being inside it), which causes it to enter only if the new string is less than or equal to the string of the first element of the array. Because of the break, the loop always ends after the first interaction.

3 answers

5

If you plan for your list to be ordered, the simplest way to do this is to directly use a std::set, which is ordered and does not allow duplicates. The code looks like this:

std::set<std::string> nomes;
nomes.insert("Pedro");
nomes.insert("Amanda");
nomes.insert("Maria");

for (auto& nome : nomes)
    std::cout << nome << std::endl; // Amanda, Maria, Pedro

(coliru)

However, if you want to keep using the std::vector, can search for the position if inserting using the std::lower_bound. But note that this function only works correctly in already ordered lists (binary search). Thus:

void sortedInsert(std::vector<std::string>& vec, std::string value) {
    auto it = std::lower_bound(vec.begin(), vec.end(), value);
    vec.insert(it, std::move(value));
}

std::vector<std::string> nomes;
sortedInsert(nomes, "Pedro");
sortedInsert(nomes, "Amanda");
sortedInsert(nomes, "Maria");

for (auto& nome : nomes)
    std::cout << nome << std::endl; // Amanda, Maria, Pedro

(coliru)
With a little more templates: (coliru)

4

I suggest you take a look at the standard STL algorithms. To solve this exact problem your already exists the lower_bound

#include <algorithm>

void inserirNomeNaLista(std::vector<string> &lista)
{
  std::string nome;
  std::cout << "Digite o nome para ser inserido na lista: ";
  std::cin >> nome;

  typedef std::vector<std::string>::iterator VecIter;
  VecIter itr = std::lower_bound(lista.begin(), lista.end(), nome);    
  lista.insert(itr, nome);
}

It searches a sequence (pair of iterators) at the point where an item should be inserted so that the sequence is in ascending order. It is efficient because it performs binary search, but only works if the sequence is always ordered. But if you only use it to insert elements into one vector there is no problem, because in this case the insertions will always be in order.


Now if this is an exercise, and you can’t use the standard algorithms, I believe your error is the position of break, as already explained nthe comment of Luiz Vieira.

1

Friend, the STL already provides the Sort() method for you. It lexicographically analyzes the strings and sorts them. Here’s an example.

#include <algorithm> //Para o sort()
#include <iostream> //Para o cout
#include <vector>  //Para o vector<>()
#include <string> //Para a string

int main() {
    std::vector<std::string> v;
    v.push_back("bac"); v.push_back("abc"); v.push_back("cab"); v.push_back("cba");
    std::sort(v.begin(),v.end());
    for(int i = 0; i < v.size(); i++) std::cout << v[i] << std::endl;
}
  • It is worth noting that for Vectors this answer is the most efficient if you insert all the strings at once (the list will not be sorted between the inserts). That’s O(nlogn) while the other (using std::lower_bound) is O(n²) in Worse case. In case you use the std::set, the complexity will be O(nlogn), but the list will always be sorted (best).

  • Perfect. Obviously it is, in fact, impossible to order the vectors at each insertion. As you said, it is more profitable to sort at the end of the inserts or use a Std:set.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.