数字误差的质因数分解

Prime factorization of number error

本文关键字:分解 质因数 误差 数字      更新时间:2023-10-16

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

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

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

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

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

修改迭代的集合:

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调整的性能要差得多
  • 我不改变方法的参数。我知道它不是通过引用传入的,但是在可能的情况下,不要影响参数总是一个好主意。

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。我不会在这里重复,因为你可以查一下。您可以将计数计算为两个迭代器之间的差值。

或者更好的是,计算因素而不删除它们,就像 Niklas 的评论一样。