Dúvida Difícil, vector em C++ [RESOLVIDO]

1. Dúvida Difícil, vector em C++ [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 01/07/2020 - 23:49h

Nem sei por onde começar! Vou explicar o que estou tentando fazer e tentar perguntar corretamente!

Eu montei 1 pequeno database usando uma Struct e depois mudei para uma Matriz de strings. OK! Acontece que no meio disso descobri vectors que nem sei como chamar corretamente o nome disso!
Então fiquei pensando se eu deveria usar vector no lugar da Matriz. Motivo pelo qual estou tentando entender o que é vector!
Se alguém achar que é uma má idéia usar vector no lugar da Matriz, me explique o motivo! Pq neste momento me pareceu ser o melhor a fazer! Mas não sei ainda!

Inicialmente o que entendi é que a partir da Matriz abaixo, vi a idéia do vector declarado logo abaixo, pois consigo ler ele no meu Grid!
std::string Database[1000][7]; // USANDO
std::vector<std::vector<std::string>> Database; // UMA IDÉIA

Então parti para estudar vector, mas tudo que acho são de arrays comuns, não o que eu quero saber!
O Problema é que quanto mais pesquiso, mais informação desencontrada e sem ligações me confundem!
Até o momento eu entendi os métodos pushback e etc... Mas não está funcionando direito! E para piorar, vi que minha declaração é um vetor de vetores!
E cada vez que pesquiso encontro mais coisas diferentes! A pouco encontrei um vetor de Struct... Uma Loucura!

No fim, eu não sei declarar o que preciso! Não sei adicionar os valores, pq dá errado! Só consegui adicionar seguindo regras exatas do que vi, mas isso não serve pra mim, e o único vector que de verdade entendi e sei fazer funcionar é assim:
std::vector<std::string> MyString; 

Neste vector acima eu sei fazer tudo, adicionar item, remover e etc... Mas nos outros dá tudo errado!

Eu pensei em usar vector, pq parece melhor, já que ele remove dados com mais facilidade, mas de verdade não sei se é melhor!

DÚVIDA 1) É melhor usar vector ao invés de uma Matriz normal? Eu pensei no Vector pq não preciso declarar um tamanho fixo de linhas, e ainda me pareceu que posso até aumentar as colunas qdo eu desejar!

No exemplo abaixo eu consigo adicionar valores, mas acho que está péssimo a forma como aprendi a fazer, pq está me obrigando a criar vetores para adicionar dados, isso é muito esquisito!
std::vector<std::vector<std::string>> Database;
// Aqui eu estou criando 3 Linhas + 3 Colunas
std::vector<std::string> Row1 = { "Linha 1", "Linha 1", "Linha 1" };
std::vector<std::string> Row2 = { "Linha 2", "Linha 2", "Linha 2" };
std::vector<std::string> Row3 = { "Linha 3", "Linha 3", "Linha 3" };

Adiciono as Linhas criadas acima para Database
Database.push_back(Row1);
Database.push_back(Row2);
Database.push_back(Row3);

Eu não quero criar vetores, o que eu quero é apenas adicionar dados de forma normal igual a minha Matriz, mas que seja claro infinito como um vetor!
Mas não consegui declarar ele igual a matriz, não consegui fazer ter sentido!

DUVIDA 2) O que preciso para entender isso?
1) Quero saber se vector é um vetor/array mesmo, ao menos é o que parece! E o que até o momento eu entendi, visto que em muitos exemplos mostram ele de forma muito simples no formato antigo de array!
2) Ficou super confuso pra mim esse lance de não precisar infomar Qtd de Colunas, quero saber se é verdade se posso aumentar ou diminuir qdo eu bem entender já com dados dentro dele! Sobre as linhas eu entendi, sei aumentar, sei diminuir!
3) Como adiciono valores a um vetor de 2 dimensões sem ter que declarar vetores com é o caso do meu exemplo louco que tenho! Vetor de 1 dimensão eu sei fazer como explico acima!

Espero que alguém tenha entendido minha pergunta, pq ontem e hoje apenas estudando isso, me deixou bastante confuso, que nem estou conseguindo formular corretamente minha pergunta, pq o raciocínio não está coerente!


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 02/07/2020 - 03:25h

Nick-us escreveu:

Nem sei por onde começar! Vou explicar o que estou tentando fazer e tentar perguntar corretamente!

Eu montei 1 pequeno database usando uma Struct e depois mudei para uma Matriz de strings. OK! Acontece que no meio disso descobri vectors que nem sei como chamar corretamente o nome disso!
Então fiquei pensando se eu deveria usar vector no lugar da Matriz. Motivo pelo qual estou tentando entender o que é vector!
Se alguém achar que é uma má idéia usar vector no lugar da Matriz, me explique o motivo! Pq neste momento me pareceu ser o melhor a fazer! Mas não sei ainda!

Inicialmente o que entendi é que a partir da Matriz abaixo, vi a idéia do vector declarado logo abaixo, pois consigo ler ele no meu Grid!
std::string Database[1000][7]; // USANDO 


Você pode imaginar isso como uma tabela com tamanho fixo de mil linhas e sete colunas, na qual cada célula pode conter um texto com um comprimento qualquer (std::string tem seus próprios métodos para cuidar do tamanho dos dados armazenados e eventuais alocações/realocações/liberações de memória que sejam necessárias para acomodar tais dados).

std::vector<std::vector<std::string>> Database; // UMA IDÉIA 


Isso não é uma tabela, mas apenas um vetor (ou uma tabela que tem apenas uma coluna).

Às vezes, especialmente ao traduzir para o Português, os arrays nativos da linguagem são chamados de “vetores”. A grande diferença é que os arrays nativos têm tamanhos fixos, ao passo que objetos do tipo std::vector podem aumentar ou diminuir a quantidade de elementos armazenados durante a vida do programa.

Então parti para estudar vector, mas tudo que acho são de arrays comuns, não o que eu quero saber!
O Problema é que quanto mais pesquiso, mais informação desencontrada e sem ligações me confundem!
Até o momento eu entendi os métodos pushback e etc... Mas não está funcionando direito! E para piorar, vi que minha declaração é um vetor de vetores!
E cada vez que pesquiso encontro mais coisas diferentes! A pouco encontrei um vetor de Struct... Uma Loucura!

No fim, eu não sei declarar o que preciso! Não sei adicionar os valores, pq dá errado! Só consegui adicionar seguindo regras exatas do que vi, mas isso não serve pra mim, e o único vector que de verdade entendi e sei fazer funcionar é assim:
std::vector<std::string> MyString; 

Neste vector acima eu sei fazer tudo, adicionar item, remover e etc... Mas nos outros dá tudo errado!

Eu pensei em usar vector, pq parece melhor, já que ele remove dados com mais facilidade, mas de verdade não sei se é melhor!

DÚVIDA 1) É melhor usar vector ao invés de uma Matriz normal? Eu pensei no Vector pq não preciso declarar um tamanho fixo de linhas, e ainda me pareceu que posso até aumentar as colunas qdo eu desejar!

No exemplo abaixo eu consigo adicionar valores, mas acho que está péssimo a forma como aprendi a fazer, pq está me obrigando a criar vetores para adicionar dados, isso é muito esquisito!
std::vector<std::vector<std::string>> Database;
// Aqui eu estou criando 3 Linhas + 3 Colunas
std::vector<std::string> Row1 = { "Linha 1", "Linha 1", "Linha 1" };
std::vector<std::string> Row2 = { "Linha 2", "Linha 2", "Linha 2" };
std::vector<std::string> Row3 = { "Linha 3", "Linha 3", "Linha 3" };

Adiciono as Linhas criadas acima para Database
Database.push_back(Row1);
Database.push_back(Row2);
Database.push_back(Row3);

Eu não quero criar vetores, o que eu quero é apenas adicionar dados de forma normal igual a minha Matriz, mas que seja claro infinito como um vetor!
Mas não consegui declarar ele igual a matriz, não consegui fazer ter sentido!


OK. Vamos voltar ao básico. Veja sua primeira declaração nesta postagem.
std::string Database[1000][7]; 

Aqui, você declara que o tipo de Database é “array com 1000 elementos do tipo «array com sete elementos do tipo std::string»”. Ou seja: o que você tem não é exatamente uma matriz de strings, mas sim um array de arrays de strings. Em outras palavras, cada elemento de Database (i.e. Database[0], Database[1], ..., Database[999]) é um array de seu próprio direto, cada um deles com sete elementos (e.g. Database[n][0], Database[n][1], ..., Database[n][6], sendo n um índice válido dos elementos de Database) do tipo std::string.

Com vetores baseados em std::vector, vale ideia semelhante. A declaração
std::vector<std::vector<std::string>> Database; 
significa que Database tem o tipo de dados ”vetor de objetos do tipo «vetor de objetos do tipo strings»”.

Você não precisa de variáveis intermediárias para popular seu vetor de vetores de strings. Desde o C++11, existe uma sintaxe de construtores baseada em listas de inicialização.
// Declara “Database” e a constrói com valores iniciais.
std::vector<std::vector<std::string>> Database{
{ "L0C0", "L0C1", "L0C2", "L0C3" },
{ "L1C0", "L1C1", "L1C2", "L1C3" },
{ "L2C0", "L2C1", "L2C2", "L2C3" },
{ "L3C0", "L3C1", "L3C2", "L3C3" },
{ "L4C0", "L4C1", "L4C2", "L4C3" }
};


DUVIDA 2) O que preciso para entender isso?
1) Quero saber se vector é um vetor/array mesmo, ao menos é o que parece! E o que até o momento eu entendi, visto que em muitos exemplos mostram ele de forma muito simples no formato antigo de array!
2) Ficou super confuso pra mim esse lance de não precisar infomar Qtd de Colunas, quero saber se é verdade se posso aumentar ou diminuir qdo eu bem entender já com dados dentro dele! Sobre as linhas eu entendi, sei aumentar, sei diminuir!
3) Como adiciono valores a um vetor de 2 dimensões sem ter que declarar vetores com é o caso do meu exemplo louco que tenho! Vetor de 1 dimensão eu sei fazer como explico acima!


Espero que os exemplos acima ajudem para as subperguntas 1 e 2.

Para a 3, você tem de lembrar que o que querendo acrescentar dados a um vetor cujos elementos são vetores de strings. Então é isso que você tem de fazer.

Se os seus elementos forem constantes, existe a forma clássica (C++98) de fazer, que é a seguinte.
Database.push_back(std::vector<std::string>());  // Insere linha vazia no final.
Database.back().push_back("L99C0"); // Insere 1ª coluna na última linha.
Database.back().push_back("L99C1"); // Insere 2ª coluna na última linha.
Database.back().push_back("L99C2"); // ...
Database.back().push_back("L99C3"); // ...


O C++11 facilitou um pouco as coisas com listas de inicialização e com o template de função-membro std::vector::emplace_back(), que encaminha seus argumentos diretamente para o construtor adequado do elemento dentro do array, em vez de construir um objeto fora do array primeiro e depois copiá-lo ou movê-lo para dentro do vetor.

Database.push_back(std::vector<std::string>{"L100C0", "L100C1", "L100C2", "L100C3"});  // Chamo explicitamente o construtor que usa lista de inicialização.

Database.emplace_back(std::initializer_list<std::string>{"L101C0", "L101C1", "L101C2", "L101C3"}); // Chama implicitamente o mesmo construtor, com base nos tipos dos argumentos.
Database.emplace_back(4, "L102C?"); // Chama implicitamente o construtor que vai criar quatro elementos iguais a “L102C?”.



... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)

3. Re: Dúvida Difícil, vector em C++ [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 06/07/2020 - 16:47h

paulo1205 escreveu:
Você pode imaginar isso como uma tabela com tamanho fixo de mil linhas e sete colunas, na qual cada célula pode conter um texto com um comprimento qualquer (std::string tem seus próprios métodos para cuidar do tamanho dos dados armazenados e eventuais alocações/realocações/liberações de memória que sejam necessárias para acomodar tais dados).

Sim detalhe importante!

Às vezes, especialmente ao traduzir para o Português, os arrays nativos da linguagem são chamados de “vetores”. A grande diferença é que os arrays nativos têm tamanhos fixos, ao passo que objetos do tipo std::vector podem aumentar ou diminuir a quantidade de elementos armazenados durante a vida do programa.

Bom Saber!

OK. Vamos voltar ao básico. Veja sua primeira declaração nesta postagem.
std::string Database[1000][7]; 

Aqui, você declara que o tipo de Database é “array com 1000 elementos do tipo «array com sete elementos do tipo std::string»”. Ou seja: o que você tem não é exatamente uma matriz de strings, mas sim um array de arrays de strings. Em outras palavras, cada elemento de Database (i.e. Database[0], Database[1], ..., Database[999]) é um array de seu próprio direto, cada um deles com sete elementos (e.g. Database[n][0], Database[n][1], ..., Database[n][6], sendo n um índice válido dos elementos de Database) do tipo std::string.

Com vetores baseados em std::vector, vale ideia semelhante. A declaração
std::vector<std::vector<std::string>> Database; 
significa que Database tem o tipo de dados ”vetor de objetos do tipo «vetor de objetos do tipo strings»”.

De forma incrível, embora devesse ser óbvio para mim, mas não foi, a partir da sua explicação montei um exemplo para ver na prática, é bem interessante quando não vemos uma coisa que está a nossa frente, A forma como eu via era mais complexa, logo confunde! Tenho que estar mais atento ao lado simples da coisa!

Você não precisa de variáveis intermediárias para popular seu vetor de vetores de strings. Desde o C++11, existe uma sintaxe de construtores baseada em listas de inicialização.
// Declara “Database” e a constrói com valores iniciais.
std::vector<std::vector<std::string>> Database{
{ "L0C0", "L0C1", "L0C2", "L0C3" },
{ "L1C0", "L1C1", "L1C2", "L1C3" },
{ "L2C0", "L2C1", "L2C2", "L2C3" },
{ "L3C0", "L3C1", "L3C2", "L3C3" },
{ "L4C0", "L4C1", "L4C2", "L4C3" }
};

você tem de lembrar que o que querendo acrescentar dados a um vetor cujos elementos são vetores de strings. Então é isso que você tem de fazer.
Se os seus elementos forem constantes, existe a forma clássica (C++98) de fazer, que é a seguinte.
Database.push_back(std::vector<std::string>());  // Insere linha vazia no final.
Database.back().push_back("L99C0"); // Insere 1ª coluna na última linha.
Database.back().push_back("L99C1"); // Insere 2ª coluna na última linha.
Database.back().push_back("L99C2"); // ...
Database.back().push_back("L99C3"); // ...


O C++11 facilitou um pouco as coisas com listas de inicialização e com o template de função-membro std::vector::emplace_back(), que encaminha seus argumentos diretamente para o construtor adequado do elemento dentro do array, em vez de construir um objeto fora do array primeiro e depois copiá-lo ou movê-lo para dentro do vetor.

Database.push_back(std::vector<std::string>{"L100C0", "L100C1", "L100C2", "L100C3"});  // Chamo explicitamente o construtor que usa lista de inicialização.

Database.emplace_back(std::initializer_list<std::string>{"L101C0", "L101C1", "L101C2", "L101C3"}); // Chama implicitamente o mesmo construtor, com base nos tipos dos argumentos.
Database.emplace_back(4, "L102C?"); // Chama implicitamente o construtor que vai criar quatro elementos iguais a “L102C?”.

Com todos esses exemplos eu já tenho a Base de como declarar, sabendo o que estou declarando e como colocar os dados no meu vector. E no fim não parece mais tão complicado quanto a primeira impressão! Vou agora alterar o programa Encyclopedia para usar um vector no lugar.

Paulo mais uma vez, muito obrigado por todos esses excelentes exemplos! Isso traz animo para programar!

A Parte boa nisso tudo, é que: Estou muito Feliz de ter evoluido em C, ainda AMO C, gosto dele, gosto de aprender sobre ele, considero extremamente importante eu saber fazer tudo nele, acho que saber fazer essas coisas em C para mim são importantes então mesmo que na maioria dos casos eu use C++ como é o caso da Encyclopedia, eu acabo estudando C++ com satisfação, e muito me facilita para entender C++ porque eu conheço a BASE das coisas como elas aconteceram!

Inicialmente eu estava meio que chateado com C++ mas suas respostas me ajudaram a entender todo o processo, estão me ajudando a entender as coisas, me permitindo gostar também de C++. Estou no momento usando String pq claro é mais fácil mesmo! Mas não abro mão de ter aprendido a trabalhar com vetor de char, eu gosto de saber como começaram as coisas, e entender um vetor de char para mim foi o início!

Assim como não esqueçi, que ainda voltarei no tempo, assim que meu programa de dicas, o que vai me facilitar anotar e consultar dúvidas estiver pronto, vou sim tentar fazer alguma coisa em assembly! Ainda estou curioso em como programar em Assembly.

Obrigado Paulo!








Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts