数字误差的素数因子分解

时间:2014-02-26 14:46:20

标签: c++ vector map

我创建了一个函数,它返回一个vector,其中包含整数的所有素因子,我正在尝试创建另一个函数,从map创建vector

但是,我得到一些典型的非法内存访问错误,我找不到它是什么。我认为它发生在for函数的map<int, int> factorizacion(vector<int>)循环内。

我希望我能在这里得到一些帮助。

我可以发布整个程序,但我会坚持导致问题的功能。如果您需要查看代码,请询问其余代码。

map<int, int> factorizacion(vector<int> v) {
    map<int, int> m;

    while (!v.empty()) {
        int elto = v.front();
        int ctd = 0;

        for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
            if (*it == elto) {
                ++ctd;
                v.erase(it);
            }
        }
        m[elto] = ctd;
    }

    return m;
}

2 个答案:

答案 0 :(得分:2)

您可以修改您迭代的集合:

for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
    if (*it == elto) {
        ++ctd;
        v.erase(it);
    }
}

如果删除迭代器指向的项目,则不能继续使用相同的迭代器。

顺便说一下,您可以利用map将自动初始化为0不存在的密钥值的事实。

此代码将执行您想要的操作:

map<int, int> m;
for (int i = 0; i < v.size(); i++) {
  m[v[i]]++;
}

唯一的问题是性能方面我的解决方案有点慢 - 它执行的查询多于最佳解决方案。但是,我建议的解决方案比你的更好(当它被修复时,因为):

  • 在向量中擦除操作成本高,占用线性时间,性能比我的map调整要差很多
  • 我不改变方法的参数。我知道它不是通过引用传递的,但是在可能的情况下不要影响参数总是一个好主意。

答案 1 :(得分:1)

v.erase(it)使it无效。你需要改变你的循环:

for (vector<int>::iterator it = v.begin(); it != v.end();) {
    if (*it == elto) {
        ++ctd;
        it = v.erase(it);
    } else {
       ++it;
    }
}

或者更好的是,使用std::remove.erase类似于“擦除 - 删除”习惯用法。我不会在这里重复,因为你可以查阅它。您可以将计数计算为两个迭代器之间的差异。

甚至更好,根据尼克拉斯的评论计算因素而不删除它们。