Ir ao conteúdo
  • Cadastre-se

C++ O algoritmo set_union de std


Bimetal

Posts recomendados

Olá pessoal. Eu venho tentando usar o algoritmo set_union porém sem sucesso. As referências dizem que o quinto parâmetro pede um output iterator só que no meu código o parâmetro não está sendo aceito e eu não consigo descobrir o por quê.

 

#include <iostream>
#include <set>
#include <string>
#include <iterator>
#include <algorithm>

int main()
{
    const char* let1[] = { "1", "2", "3", "4", "5", "6" };
    const char* let2[] = { "1", "3", "5", "7", "8", "9" };

    std::set<std::string> set1(let1, let1 + 6), set2(let2, let2 + 6), set3;
    set3.get_allocator().allocate(10);

    std::cout << "Set1: ";
    std::copy(set1.begin(), set1.end(), std::ostream_iterator<std::string, char, std::char_traits<char>>(std::cout, " "));
    std::cout << std::endl << std::endl;

    std::cout << "Set2: ";
    std::copy(set2.begin(), set2.end(), std::ostream_iterator<std::string, char, std::char_traits<char>>(std::cout, " "));
    std::cout << std::endl << std::endl;

    std::cout << "Union: ";
    std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), set3.begin());
    std::copy(set3.begin(), set3.end(), std::ostream_iterator<std::string, char, std::char_traits<char>>(std::cout, " "));
    std::cout << std::endl << std::endl;

    return EXIT_SUCCESS;
}

Alguém sabe me dizer por que isso está acontecendo? Quem puder me esclarecer isso eu agradeço.

Link para o comentário
Compartilhar em outros sites

//std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), set3.begin());
std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(),   std::inserter(set3, set3.begin()));

O std::set não aceita push_back, por isso a sintaxe deve ser acima. Alternativamente você pode usar "vector" ao invés de "set ".

#include <iostream>
#include <set>
#include <string>
#include <iterator>
#include <algorithm>
#include <vector>   

int main()
{
    const char* let1[] = { "1", "2", "3", "4", "5", "6" };
    const char* let2[] = { "1", "3", "5", "7", "8", "9" };

    std::vector<std::string> set1(let1, let1 + 6), set2(let2, let2 + 6), set3(12);
    

    std::cout << "Set1: ";
    std::copy(set1.begin(), set1.end(), std::ostream_iterator<std::string, char, std::char_traits<char>>(std::cout, " "));
    std::cout << std::endl << std::endl;

    std::cout << "Set2: ";
    std::copy(set2.begin(), set2.end(), std::ostream_iterator<std::string, char, std::char_traits<char>>(std::cout, " "));
    std::cout << std::endl << std::endl;

    std::cout << "Union: ";
    std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(),   set3.begin());
    std::copy(set3.begin(), set3.end(), std::ostream_iterator<std::string, char, std::char_traits<char>>(std::cout, " "));
    std::cout << std::endl << std::endl;

    return EXIT_SUCCESS;
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Olá

 

 

Não entendi seu programa. Não estou certo de que sei o que você pretendia fazer.

Parece muito complicado.

 

Mas

set3.get_allocator().allocate(10);

Que quer fazer com isso? allocate() devolve um ponteiro e você nada faz com ele.
 

1 hora atrás, Bimetal disse:

As referências dizem que o quinto parâmetro pede um output iterator só que no meu código o parâmetro não está sendo aceito

 

std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), set3.begin());

Se set3 é std::set<> então o que faz você imaginar que set3.begin() seja um output iterator e não um std::set<>::iterator? Por certo que o compilador vai rejeitar...

 

Pode usar inserter() que é um tipo de output iterator ou usar outra técnica, como um loop e um copy ou usar for_each() ou derivar set e definir operator+ para uniao, - por exemplo.

 

Acho que tentou adaptar esse exemplo

// set_union example
#include <iostream>     // std::cout
#include <algorithm>    // std::set_union, std::sort
#include <vector>       // std::vector

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0
  std::vector<int>::iterator it;

  std::sort (first,first+5);     //  5 10 15 20 25
  std::sort (second,second+5);   // 10 20 30 40 50

  it=std::set_union (first, first+5, second, second+5, v.begin());
                                               // 5 10 15 20 25 30 40 50  0  0
  v.resize(it-v.begin());                      // 5 10 15 20 25 30 40 50

  std::cout << "The union has " << (v.size()) << " elements:\n";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

de http://www.cplusplus.com/reference/algorithm/set_union/ para rodar com set.

 

note que set_union() curiosamente nada tem a ver com set mas sim com sorted ranges

 

Vou deixar um curto exemplo que lista os conjuntos usando um simples loop e depois ou output iterator só pra mostrar a união. E depois fazer a mesma coisa usando algoritmos. Talvez seja isso que procura.

 

Eis a saida


conjuntos A, B e (A uniao B) usando loops

Set 1: 1 2 3 4 5 6
Set 2: 1 3 5 7 8 9
[apenas saida]
Set 3: 1 2 3 4 5 6 7 8 9

conjuntos A, B e (A uniao B) usando algoritmos

Set 1: 1 2 3 4 5 6
Set 2: 1 3 5 7 8 9
Set 3: 1 2 3 4 5 6 7 8 9

[usando for_each] Set 4: 1 2 3 4 5 6 7 8 9

 

E o programa

 

#include <iostream>
#include <set>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;

int main()
{
    const char* let1[] = { "1", "2", "3", "4", "5", "6" };
    const char* let2[] = { "1", "3", "5", "7", "8", "9" };
    set<string> set1(let1, let1 + 6);
    set<string> set2(let2, let2 + 6);

    // usando loops e sem criar o vetor

    cout << "\nconjuntos A, B e (A uniao B) usando loops\n";
    cout << "\nSet 1: "; for (auto x : set1) cout << x << " ";
    cout << "\nSet 2: "; for (auto x : set2) cout << x << " ";
    cout << "\n[apenas saida]\nSet 3: ";
    ostream_iterator<string> iter_saida{ cout, " " };
    std::set_union(
        set1.begin(), set1.end(), 
        set2.begin(), set2.end(),
        iter_saida // iterador de saida associado a cout
        );
    cout << "\n";

    // usando algoritmos

    cout << "\nconjuntos A, B e (A uniao B) usando algoritmos\n";
    cout << "\nSet 1: ";
    copy(set1.begin(), set1.end(), iter_saida);
    cout << "\nSet 2: ";
    copy(set2.begin(), set2.end(), iter_saida);
    set<string> set3;
    std::set_union(
        set1.begin(), set1.end(),
        set2.begin(), set2.end(),
        inserter(set3, set3.begin())
    );
    cout << "\nSet 3: ";
    copy(set3.begin(), set3.end(), iter_saida);
    cout << "\n";

    // usando for_each()

    set<string>set4;
    for_each(
        set1.begin(), set1.end(),
        [&set4](string i) {set4.insert(i); });
    for_each(
        set2.begin(), set2.end(), 
        [&set2,&set4](string i)
        { if(set2.end() != set2.find(i)) set4.insert(i); });
    cout << "\n[usando for_each] Set 4: ";
    copy(set4.begin(), set4.end(), iter_saida);
    cout << "\n";

    return EXIT_SUCCESS;
}

 

Faz várias vezes a mesma coisa, afinal é só um exemplo. Espero que ajude

 

adicionado 1 minuto depois
47 minutos atrás, Flávio Pedroza disse:

O std::set não aceita push_back, por isso a sintaxe deve ser acima. Alternativamente você pode usar "vector" ao invés de "set "

 

Não entendi o que significa o push_back aqui 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...