【问题标题】:How to access to the index of a 2D vector by at() function?如何通过 at() 函数访问二维向量的索引?
【发布时间】:2014-09-01 19:02:18
【问题描述】:

我将在成员函数中初始化一个 2D 向量,其中输入参数计划被馈送到函数参数中确定的索引中。 此外,出于安全考虑,我不会使用 [] 运算符来访问成员。 如何使用 at() 函数来访问二维向量的索引,如下所示?

vector<vector<double>> weight;

void Connection::setWeight(const double& value, const double& i, const double& j)
{
    // The other scheme except: weight[i][j] = value;
}

【问题讨论】:

  • weight.at(i).at(j) = value;
  • +1 - 我不明白为什么这个问题值得一票否决。
  • @MaxBeikirch 因为通过查看一些文档来解决这个问题很简单?
  • @jaunchopanza:也许你不相信我,但我在网上浏览了一段时间后在这里提出了这个问题,以找到不止一个维度......但谢谢你的澄清文档的潜在功能!!!
  • 向量永远不会超过一维。您需要从“监管链”的角度进行思考;您从外部向量中获取内部向量,然后对该内部向量执行新操作。

标签: c++ c++11 vector


【解决方案1】:

您可以使用两次at。另请注意,如果ij 是索引,它们真的不应该是double

void Connection::setWeight(const double value, const size_t i, const size_t j)
{
    weight.at(i).at(j) = value;
}

【讨论】:

  • 你的意思是它们应该是整数,就像索引类型的内在本质一样,对吧?
  • size_t 实际上是unsigned int,因为您不能使用负索引。
【解决方案2】:

premature optimization 有被否决的风险,并且因为它并没有真正回答所提出的问题,我仍然想提醒一下这种方法中的一个严重问题。

与任何多维数组一样,向量的向量不是连续的,由于缺少spatial locality 和关联的cache misses,导致其性能特征非常糟糕。

您可以通过使用二维数组的方便接口包装一维数组来轻松解决问题。

template <class T>
class MyArray2D
{
    std::vector<T> data;
    size_t sizeX, sizeY;
public:

const T& at(int x, int y) const { return data.at(y + x * sizeY); }

T& at(int x, int y) { return data.at(y + x * sizeY); }

// wrap other methods you need of std::vector here
};

请注意,上面的代码是即时编写的,并未编译。不过,我相信你已经明白了。

另见:

【讨论】:

  • “过早优化有被否决的风险,...”我给你一个初始费用;)。您的观点有效且相关。
  • @Drop:你断言这种情况下的性能很糟糕......那么你对线性代数和矩阵操作的有效数据结构有什么建议?!鉴于性能,您能否解释一下为什么您的 sn-p 可能优于 2D 向量?
  • @matinging 好吧,“糟糕的性能”实际上是描述我对多维数组如何工作的主观理解的一种糟糕且不专业的方式。当然,您需要在应用程序的上下文中进行分析和思考。也许向量的向量对你来说很好,你不需要在你的代码中引入额外的复杂性。但是,作为一个起点,我建议尝试为std:vector 制作一个这样的自定义包装器,并将其性能与原始方法进行比较。此外,我个人发现它在许多应用程序中都有帮助,从俄罗斯方块 ;) 到复杂的数学应用程序。
  • @matinging CPU 缓存在我们这个时代非常重要,所以我们不能放弃任何滥用它的可能性(以及多线程、向量化和分支预测)。如果您点击“另请参阅”链接,则会给出很好的解释,所以我不想重复它。 (而且我可能无法更好地解释它)
  • @Drop: +1 许可和资源 :D,尽管我仍然不能考虑我的情况的其他方法!...
猜你喜欢
  • 2023-04-03
  • 2014-07-26
  • 2015-08-14
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多