HOWTO · C++
Declare um array de vetores em C++ STL
Este artigo apresenta como declarar um array de vetores em C++
Nesta página
Este guia mostra como declarar um número fixo de vetores ou um vetor de vetores redimensionável em C++. O contêiner externo determina quantas linhas podem ser adicionadas; cada std::vector interno determina quantos valores essa linha contém. Escolha a primeira forma quando o número de linhas for fixo e a segunda quando a coleção externa precisar crescer ou diminuir.
Escolha entre um array fixo e um vetor de vetores
Um array de vetores tem um número de linhas fixado em tempo de compilação, enquanto cada linha continua sendo um vetor que pode crescer de forma independente. Um vetor de vetores também pode mudar a quantidade de linhas, e cada linha pode ter um comprimento diferente. Portanto, um vetor de vetores não é automaticamente uma matriz retangular. Ele é útil para dados como listas de adjacência, nas quais cada elemento pode ter uma quantidade diferente de vizinhos.
Nas duas formas, os vetores são armazenados como elementos e gerenciam a própria memória. Nenhuma das declarações garante que todas as linhas contenham a mesma quantidade de valores. Se o algoritmo exigir uma estrutura retangular, inicialize cada linha com a mesma largura e mantenha essa condição ao modificar os dados.
Declare um array de vetores com a sintaxe de array no estilo C
Para usar um número fixo de linhas, declare um array cujo tipo de elemento seja std::vector<int>, por exemplo, std::vector<int> rows[3];. O array tem três elementos do tipo vetor. Eles começam vazios, mas você pode acrescentar valores a uma linha com rows[0].push_back(10). O próprio array não pode crescer para comportar um quarto vetor; use um contêiner externo redimensionável se a quantidade de linhas precisar mudar.
Essa sintaxe é útil quando a quantidade de linhas faz parte da estrutura fixa do programa. O tamanho do array é determinado pela declaração, enquanto o tamanho de cada vetor pode mudar durante a execução. Assim, as duas dimensões seguem regras diferentes: o array externo tem tamanho fixo, e os vetores internos podem ser redimensionados.
Declare um vetor de vetores redimensionável
Use std::vector<std::vector<int>> quando a quantidade de linhas precisar poder mudar. Uma lista de inicializadores pode criar linhas com comprimentos iniciais diferentes. Outra opção é std::vector<std::vector<int>> rows(3, std::vector<int>(2, 0));, que cria três linhas, cada uma com dois zeros. Nessa forma do construtor, o primeiro argumento é a quantidade de linhas; o segundo é um vetor copiado para inicializar cada linha.
Você pode acrescentar uma linha com rows.push_back({8, 9}) ou adicionar um valor a uma linha existente com rows[0].push_back(7). Aumentar ou reduzir uma linha não redimensiona automaticamente as demais. Escolha a forma com construtor para começar com uma grade regular; use uma lista de inicializadores ou construa as linhas uma a uma quando os comprimentos forem diferentes.
Acesse e percorra um vetor de vetores
Use rows[row][column] para acessar diretamente um elemento quando souber que os índices são válidos. Cada operador de índice é aplicado a um vetor diferente: o primeiro seleciona uma linha externa, e o segundo seleciona um valor dentro dela. Como as linhas podem ter comprimentos diferentes, um índice de coluna válido para uma linha pode não ser válido para outra.
Use rows.at(row).at(column) quando quiser acesso com verificação de limites; at() informa um acesso fora dos limites em vez de indexar silenciosamente além do vetor selecionado. Para percorrer todos os valores sem presumir que as linhas têm o mesmo comprimento, use loops baseados em intervalo aninhados. Associe o valor interno por referência (int& value) quando o loop precisar modificar os elementos armazenados; para leitura, use uma cópia ou uma referência constante. O exemplo completo abaixo demonstra as duas formas de declaração, o acesso por índices, o acesso com verificação de limites, a inclusão de elementos e a modificação por referência.
Este programa completo apresenta as duas estruturas de contêiner e acessa seus valores:
O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.
#include <iostream>
#include <vector>
int main() {
std::vector<int> fixed_rows[3] = {{1, 2}, {3}, {4, 5, 6}};
std::vector<std::vector<int>> rows{{1, 2}, {3}, {4, 5, 6}};
fixed_rows[0].push_back(7);
rows.push_back({8, 9});
rows[1].push_back(7);
rows.at(0).at(1) = 20;
std::cout << fixed_rows[0][2] << '\n';
std::cout << rows.at(0).at(1) << '\n';
for (auto& row : rows) {
for (int& value : row) {
value *= 2;
std::cout << value << ' ';
}
std::cout << '\n';
}
}