1

我需要在 C++ 中存储整数和双精度值的集合(代表名义值和实值数据)。我显然可以将它们全部存储在 a 中std::vector<double>,但这感觉有点不对,并且没有获得美学加分。

我也可以根据多态性来做一些事情,但我还需要集合非常高效:在集合中存储和检索数据都应该尽可能快。我发现很难判断这样的解决方案是否会最大限度地提高效率。

我还找到了boost::variant,这在这里可能会有所帮助。

附加信息:集合中的项目数将很小(<100)并且在初始化集合时已知。

总结:我显然可以用无数种方法解决这个问题,但是当(i)效率非常重要并且(ii)我也想编写一些不错的代码时,我不确定什么是一个好的解决方案。我在这里最好的选择是什么?

编辑,附加信息:该集合代表较大数据集中的“行”,其元素代表某些“列”的值。行的属性是已知的,因此知道什么样的数据存储在哪个位置。我所说的“效率”主要是检索某个列的 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 列和 double 列存储在两个单独的向量中是一个可靠的解决方案。然后,该集合Row可以只定义两个不同的成员来检索函数可以使用的名义数据和真实数据。

我猜只是存储为 avector<double>也可以,但这取决于 double 和 int 之间的转换速度有多快(这可能令人印象深刻)。

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

4

5 回答 5

5

在您的容器中订购是一个重要的点吗?

如果不是这样:

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

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

   ....
};

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

于 2009-10-16T12:27:31.087 回答
5

为什么不直接使用双精度向量?由于整数可以在不损失精度的情况下转换为双精度......在我看来这是最简单和最有效的解决方案。

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

于 2009-10-16T12:34:52.803 回答
3

您可以使用联合类型并在向量中使用它。但在这种情况下,您必须有一些方法来知道向量的哪些元素应该被视为整数,哪些元素应该被视为双精度数。要跟踪哪些是整数,哪些是双精度数,您可以使用 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;
}
于 2009-10-16T12:14:21.893 回答
3

我会寻求boost::variant解决方案,它完全符合您的需求。

于 2009-10-16T12:29:19.730 回答
1

如果您在编译时知道类型,则可以使用 boost 元组。但是,如果项目的数量很少,那么有效地浪费 100 个字节就不是问题了。

于 2009-10-16T12:27:55.020 回答