C++ 如何验证向量在某个索引处是否有值

C++ 如何验证向量在某个索引处是否有值,c++,performance,random-walk,C++,Performance,Random Walk,在“自回避随机游走”的情况下,我有一个具有阶跃坐标配置的二维向量。我希望能够检查某个站点是否已被占用,但问题是轴可以为零,因此检查坐标的fabs()是否为true(或是否有值)将不起作用。因此,我考虑过在步骤中循环并检查我的坐标是否等于所有轴上的另一个坐标,如果等于,请后退一步并重试(所谓的深度优先方法) 有没有更有效的方法?我见过有人用布尔数组来表示所有可能的坐标,如下所示: bool occupied[nMax][nMax]; // true if lattice site

在“自回避随机游走”的情况下,我有一个具有阶跃坐标配置的二维向量。我希望能够检查某个站点是否已被占用,但问题是轴可以为零,因此检查坐标的
fabs()
是否为
true
(或是否有值)将不起作用。因此,我考虑过在步骤中循环并检查我的坐标是否等于所有轴上的另一个坐标,如果等于,请后退一步并重试(所谓的深度优先方法)

有没有更有效的方法?我见过有人用布尔数组来表示所有可能的坐标,如下所示:

bool occupied[nMax][nMax];          // true if lattice site is occupied
for (int y = -rMax; y <= rMax; y++)
        for (int x = -rMax; x <= rMax; x++)
            occupied[index(y)][index(x)] = false;
bool占用[nMax][nMax];//如果晶格位置被占用,则为true

对于(int y=-rMax;y,您的问题与算法有关,而不是与(C++)语言的使用有关,因此这里是一个一般性的答案

您需要的是一个数据结构来存储一组(点坐标),并使用一个有效的操作来查询新点是否在该集合中

将集合显式存储为布尔数组提供了恒定时间查询(最快),但空间的维数是指数级的

穷举搜索(您的第二个选项)提供的查询在设置大小(行走长度)上是线性的,在设置大小上也是线性的,并且与维度无关

其他两个常用选项是树结构和哈希表,例如可用作
std::set
(通常使用红黑树)和
std::unordered_set
(后者仅在C++11中)。树结构通常具有对数时间查询,而哈希表查询在实践中可以是常数时间,几乎使您回到布尔数组的复杂性。但在这两种情况下,所需的空间在设置的大小中都是线性的,并且与维度无关。

您可以在O(logn)或O(1)中执行此检查分别使用STL集合或无序集合的时间。无序集合容器要求您为坐标编写自定义哈希函数,而集合容器只需要您提供比较函数。集合实现特别简单,对数时间应该足够快:

#include <iostream>
#include <set>
#include <vector>
#include <cassert>

class Position {
public:
    Position(const std::vector<long int> &c)
        : m_coords(c) { }

    size_t dim() const { return m_coords.size(); }
    bool operator <(const Position &b) const {
        assert(b.dim() == dim());
        for (size_t i = 0; i < dim(); ++i) {
            if (m_coords[i] < b.m_coords[i])
                return true;
            if (m_coords[i] > b.m_coords[i])
                return false;
        }
        return false;
    }

private:
    std::vector<long int> m_coords;
};

int main(int argc, const char *argv[])
{
    std::set<Position> visited;
    std::vector<long int> coords(3, 0);
    visited.insert(Position(coords));

    while (true) {
        std::cout << "x, y, z: ";
        std::cin >> coords[0] >> coords[1] >> coords[2];
        Position candidate(coords);
        if (visited.find(candidate) != visited.end())
            std::cout << "Aready visited!" << std::endl;
        else
            visited.insert(candidate);
    }
    return 0;
}
#包括
#包括
#包括
#包括
阶级地位{
公众:
位置(常数标准::向量和c)
:m_coords(c){}
size_t dim()常量{返回m_coords.size();}
布尔算子b.m_坐标[i])
返回false;
}
返回false;
}
私人:
std::向量m_坐标;
};
int main(int argc,const char*argv[]
{
std::访问的集合;
std::向量坐标(3,0);
访问。插入(位置(坐标));
while(true){
标准::cout>coords[0]>>coords[1]>>coords[2];
职位候选人(coords);
if(visted.find(candidate)!=visted.end())

std::cout Nice。我想你的比较运算符可以使用
std::lexicographical\u compare
。哦,是的,那会有用的。虽然,它不会捕捉到比较不同维度坐标的情况。@JulianPanetta我不是一个足够熟练的程序员,无法完全理解这个解决方案,我将阅读一些参考资料NictraSavios:我只是补充了一点解释。希望现在更清楚。注意:所提出算法的空间/时间复杂性与维度无关(这是不可能的).相反,节省空间的算法在维数上是线性的。当然,维数可能很小,因此只要相关性不是指数性的,就可以忽略。
#include <iostream>
#include <set>
#include <vector>
#include <cassert>

class Position {
public:
    Position(const std::vector<long int> &c)
        : m_coords(c) { }

    size_t dim() const { return m_coords.size(); }
    bool operator <(const Position &b) const {
        assert(b.dim() == dim());
        for (size_t i = 0; i < dim(); ++i) {
            if (m_coords[i] < b.m_coords[i])
                return true;
            if (m_coords[i] > b.m_coords[i])
                return false;
        }
        return false;
    }

private:
    std::vector<long int> m_coords;
};

int main(int argc, const char *argv[])
{
    std::set<Position> visited;
    std::vector<long int> coords(3, 0);
    visited.insert(Position(coords));

    while (true) {
        std::cout << "x, y, z: ";
        std::cin >> coords[0] >> coords[1] >> coords[2];
        Position candidate(coords);
        if (visited.find(candidate) != visited.end())
            std::cout << "Aready visited!" << std::endl;
        else
            visited.insert(candidate);
    }
    return 0;
}