用 0 初始化的 int 向量给出非零值

Posted

技术标签:

【中文标题】用 0 初始化的 int 向量给出非零值【英文标题】:Vector of int initialized with 0s on acces gives non zero value 【发布时间】:2019-01-24 20:27:28 【问题描述】:

我编写了一个简单的算法来查找图中的奇数循环。我有一个访问过的向量,它告诉我一个向量是否被访问过,它被初始化为 0。

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

#define UNVISITED 0
#define VISITED 1

using namespace std;

int vertices, edges;

vector<vector<int>> graph;
vector<int> visited;
vector<int> times;

int time_ = 1;
int hasOddCycle = false;

void dfs(int vertex) 
    if (visited.at(vertex) == VISITED)
        return;
    visited.at(vertex) = VISITED;
    times.at(vertex) = time_;
    time_++;

    for (auto elem: graph.at(vertex)) 
        if (visited.at(elem) == VISITED) 
            if (times.at(vertex) - times.at(elem) % 2 == 0)
                hasOddCycle = true;
         else 
            dfs(elem);
        
    


int main() 
    cin >> vertices >> edges;

    for (int i = 0; i <= vertices; i++) 
        visited.emplace_back(UNVISITED);
        graph.emplace_back(vector<int>());
        times.push_back(0);
    

    int from, to;
    for (int i = 0; i < edges; i++) 
        cin >> from >> to;
        graph.at(from).push_back(to);
        graph.at(to).push_back(from);
    

    for (int i = 1; i <= vertices; i++) 
        dfs(i);
        if (hasOddCycle) 
            cout << "NO" << endl;
            return 0;
        
    

    cout << "YES" << endl;

    return 0;

当我使用给定数据运行我的代码时,调用 dfs(1) 并将访问的设置为 1 到 0。dfs 循环中的第一个元素是 2,所以我检查是否访问了顶点 2,它无缘无故地给了我真的! !!我不知道为什么会这样......

输入数据(顶点、边数和比顶点):

5 6
1 2
2 3
3 4
4 1
1 5
5 3

【问题讨论】:

最好的解决方案是在调试器中运行你的程序,分析所有数据点,看看什么时候行为不符合你的预期。延伸阅读:ericlippert.com/2014/03/05/how-to-debug-small-programs 我做了,调试器显示在 2 处访问的向量中的值应该是 0,但它不是 在哪一行变成 2 而不是 0? 那么您现在可以检查错误来自何处。 if (visited.at(elem) == VISITED) 行中,elem 的值为 2,visited.at(2) 的值应为 0,但事实并非如此。它发生在第一个 dfs 调用中。 【参考方案1】:

您的访问验证已关闭,全局 time_ 变量使其难以跟踪。由于times 向量提供与visited 向量相同的信息,因此我删除了visited。每次您从main 调用dfs 时,图中每个顶点的访问次数都会增加一。当函数返回时,它们都将具有相同的访问次数。以下是跟踪访问的另一种方法,使其更容易跟踪:

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

using namespace std; // bad practice

int vertices, edges;

vector<vector<int>> graph;
vector<int> times;

void dfs(int vertex) 
    static int indent = 1; // to indent recursion level in debug print

    int time_ = ++times.at(vertex);

    for (auto elem : graph.at(vertex)) 
        if (times.at(elem) != time_) 
            std::cout << std::string(indent, ' ') << "dfs(" << elem
                      << ") in graph @ vertex " << vertex << "\n";
            ++indent;
            dfs(elem);
            --indent;
        
    


int main() 
    cin >> vertices >> edges;

    times.resize(vertices+1);
    for (int i = 0; i <= vertices; i++) 
        graph.emplace_back(vector<int>());
    

    int from, to;
    for (int i = 0; i < edges; i++) 
        cin >> from >> to;
        graph.at(from).push_back(to);
        graph.at(to).push_back(from);
    

    for(int v=1; v<=vertices; ++v) 
    std::cout << "\nchecking graph from vertex " << v << "\n";
        dfs(v);
        for (int i = 1; i <= vertices; i++) 
            if (times[i] != v) 
                std::cout << " Error\n";
                return 0;
            
        
        std::cout << " all vertices has " << v << " visitation(s)\n";
    

    return 0;

输出:

checking graph from vertex 1
 dfs(2) in graph @ vertex 1
  dfs(3) in graph @ vertex 2
   dfs(4) in graph @ vertex 3
   dfs(5) in graph @ vertex 3
 all vertices has 1 visitation(s)

checking graph from vertex 2
 dfs(1) in graph @ vertex 2
  dfs(4) in graph @ vertex 1
   dfs(3) in graph @ vertex 4
    dfs(5) in graph @ vertex 3
 all vertices has 2 visitation(s)

checking graph from vertex 3
 dfs(2) in graph @ vertex 3
  dfs(1) in graph @ vertex 2
   dfs(4) in graph @ vertex 1
   dfs(5) in graph @ vertex 1
 all vertices has 3 visitation(s)

checking graph from vertex 4
 dfs(3) in graph @ vertex 4
  dfs(2) in graph @ vertex 3
   dfs(1) in graph @ vertex 2
    dfs(5) in graph @ vertex 1
 all vertices has 4 visitation(s)

checking graph from vertex 5
 dfs(1) in graph @ vertex 5
  dfs(2) in graph @ vertex 1
   dfs(3) in graph @ vertex 2
    dfs(4) in graph @ vertex 3
 all vertices has 5 visitation(s)

【讨论】:

以上是关于用 0 初始化的 int 向量给出非零值的主要内容,如果未能解决你的问题,请参考以下文章

使用非零值初始化可选的 @AppStorage 属性

C ++:如何用非零大小初始化地图中的向量

如何从向量初始化 valarray?

如何在 C++ 中初始化向量 [重复]

英特尔 SIMD - 如何检查 __m256* 是不是包含任何非零值

我们如何在 C++ 中初始化所有值为 0 的向量 [重复]