首页 文章

最有效的方式来存储混合的双打和整数集合

提问于
浏览
1

我需要在c中存储一组int和double(代表名义和实际值数据) . 我显然可以将它们全部存储在 std::vector<double> 中,但这感觉有点不对,并没有获得美学奖励积分 .

我也可以基于多态来烹饪一些东西,但我也需要集合非常有效:存储和检索集合中的数据应该尽可能快 . 我发现很难判断这样的解决方案是否最有效 .

我也找到了boost::variant,这可能对你有所帮助 .

附加信息:集合中的项目数量很少(<100),并在初始化集合时已知 .

总结:我显然可以通过无数种方式解决这个问题,但我不确定在(i)效率非常重要和(ii)我还想编写一些不错的代码时,什么是一个好的解决方案 . 我最好的选择是什么?

Edit, additional info: 该集合在较大的数据集中表示'row',其元素表示某些'columns'的值 . 行的属性是已知的,因此知道在哪个位置存储什么类型的数据 . 我所说的'efficiency'主要是检索某列的int / double值的效率,尽管快速设置值也很重要 . 我有一些函数可以对需要尽快检索的数据进行操作 . 例:

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];
    ...
}

经过一番思考和阅读建议到目前为止,似乎只是将int列和双列存储在两个单独的向量中是一个可靠的解决方案 . 然后,集合 Row 可以定义两个不同的成员,用于检索函数可以使用的名义和实际数据 .

我想,只是存储为 vector<double> 也没关系,但这取决于double和int之间的转换速度有多快(这可能相当令人印象深刻) .

抱歉一开始有点不清楚,我希望现在更清楚了,我可以对此事有更多的想法 .

5 回答

  • 3

    订购容器中的重点是什么?

    如果不是这样:

    class MyContainer
    {
        std::vector<double> doubles;
        std::vector<int>    ints;
    
        push(double value) { doubles.push_back(value); }
        push(int value)    { ints.push_back(value); }
    
       ....
    };
    

    迭代器部分(浏览整个容器)可能有点棘手......

  • 1

    为什么不直接使用double的向量?由于整数可以转换为双精度而不会损失精度......它在我看来是最简单,最有效的解决方案 .

    还有什么要设置(我无法从你的问题中找出)你如何区分正常值和实际值 . 在您可能选择的任何解决方案中,问题仍然存在 .

  • 3

    您可以使用联合类型并在向量中使用它 . 但在这种情况下,您必须有一些方法可以知道向量的哪些元素应该被视为整数,哪些元素应该被视为双精度 . 要跟踪哪些是整数以及哪些是双精度数,您可以使用bitset或类似的东西 .

    我不确定你的目标是避免重浮点计算 . 如果是,那么bitset可能更有效 . 如果没有,并且精确的int精度并不重要,那么你也可以将它们全部存储为双精度 .

    #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;
    }
    
  • 5

    我会选择 boost::variant 解决方案,它完全符合您的需求 .

  • 5

    有一个boost元组,如果你在编译时知道类型,你可以使用它 . 但是如果项目数量很少,那么浪费100个字节就不会有效 .

相关问题