Pergunta

Preciso armazenar uma coleção de INTs e duplas (representando dados nominais e com valor real) no C ++. Eu obviamente poderia armazená -los todos em um std::vector<double> , mas isso parece um pouco errado e não recebe os pontos de bônus da estética.

Eu também poderia preparar algo com base no polimorfismo, mas também preciso que a coleção seja realmente eficiente: armazenar e recuperar os dados na coleção deve ser o mais rápido possível. Acho difícil julgar se essa solução seria maximamente eficiente.

Eu também encontrei Boost :: Variante, o que pode ajudar aqui.

Informações adicionais: O número de itens da coleção será pequeno (<100) e conhecido ao inicializar a coleção.

Resumindo: obviamente, eu poderia resolver isso de inúmeras maneiras, mas não tenho certeza de qual seria uma boa solução quando (i) a eficiência for realmente importante e (ii) também quero escrever um código um pouco bom. Qual é a minha melhor aposta aqui?

Editar informações adicionais: A coleção representa uma 'linha' em um conjunto de dados maior, seus elementos representam os valores de certas 'colunas'. As propriedades das linhas são conhecidas; portanto, sabe -se que tipo de dados é armazenado em qual posição. A 'eficiência' de que estou falando é principalmente a eficiência de recuperar o valor int/duplo de uma determinada coluna, embora a configuração rápida dos valores também seja importante. Tenho algumas funções que operam nos dados que precisam recuperá -los o mais rápido possível. Exemplo:

typedef std::vector<double> Row;

void doubleFun(Row const &row)
{
    // Function knows there's always a double at index 0
    double value = row[0];
    ...
}

void integerFun(Row const &row)
{
    // Function knows there's always an integer at index 1
    int value = row[1];
    ...
}

Depois de um pouco mais de pensamento e leitura das sugestões até agora, parece que apenas armazenar colunas int e colunas duplas em dois vetores separados é uma solução sólida. A coleção Row poderia então definir dois membros diferentes para recuperar dados nominais e reais que as funções podem usar.

Apenas armazenando como um vector<double> É bom também, eu acho, mas depende da rapidez com que a conversão entre duplo e int é (o que provavelmente é bastante impressionante).

Desculpe por ser um pouco claro no começo, espero que esteja mais claro e agora e que eu possa ter mais pensamentos sobre o assunto.

Foi útil?

Solução

O pedido é um ponto importante em seu contêiner?

Se não assim:

class MyContainer
{
    std::vector<double> doubles;
    std::vector<int>    ints;

    push(double value) { doubles.push_back(value); }
    push(int value)    { ints.push_back(value); }

   ....
};

A parte do iterador (para navegar o contêiner inteiro) pode ser um pouco mais complicado ...

Outras dicas

Por que não usar diretamente um vetor duplo? Como os números inteiros podem ser convertidos em duplas sem perda de precisão ... isso me parece a solução mais simples e eficiente.

O que resta a ser definido (e eu não consegui descobrir a partir da sua pergunta) como você pode fazer a diferença entre valores normais e reais. O problema permanece aberto em qualquer solução que você escolher.

Você pode usar um tipo de união e usar isso em seu vetor. Mas, nesse caso, você teria que ter alguma maneira de saber quais elementos do vetor devem ser tratados como INTs e quais devem ser tratados como duplas. Para acompanhar quais são INTs e quais são duplas, você pode usar um bitset ou algo assim.

Não tenho certeza se seu objetivo é evitar cálculos de ponto flutuante pesado. Se for, o bitset pode ser mais eficiente. Caso contrário, e exato Int Precision não é importante, então você pode armazená -los todos como duplos.

#include <vector>
#include <bitset>

union di
{
    double d;
    int i;
};


int main(int argc, char* argv[])
{

    std::bitset<2> bitsetInts;

    std::vector<di> v;
    di e1;
    e1.d = 3.9;
    v.push_back(e1);

    di e2;
    e2.i = 3;
    bitsetInts.set(1);
    v.push_back(e2);

    return 0;
}

Eu iria para o boost::variant Solução, ele se adapta perfeitamente às suas necessidades.

Existe a tupla de impulso, que você pode usar se souber os tipos no horário de compilação. Mas se o número de itens for pequeno, com eficiência desperdiçar 100 bytes não deve ser uma preocupação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top