【问题标题】:How to test if size_t -1 is not undefined, where size_t is 0?如何测试 size_t -1 是否未定义,其中 size_t 为 0?
【发布时间】:2020-06-21 12:31:37
【问题描述】:

这个问题涉及对邻接矩阵进行深度优先搜索的边缘。
给定一个邻接矩阵:

{1,0,0,1},
{1,1,0,0},
{0,0,0,1},
{1,1,1,1}

我有一个像这样完美运行的 DFS:

typedef std::vector<std::vector<short>> matrix;

void myClass::dfs(short row, short column, std::shared_ptr<matrix> m_visited, const matrix &sky) {
    
    if (m_visited->at(row).at(column) == 1) {
        return;
    }
    m_visited->at(row).at(column) = 1; //Mark the node as visited
    if(row+1 <= sky.size()-1 && sky.at(row+1).at(column) == 1) { //Look horizontally forward
        dfs(row+1, column, m_visited, sky);
    }
    if(row-1 >= 0 && sky.at(row-1).at(column) == 1) { //Look horizontally backward
        dfs(row-1, column, m_visited, sky);
    }
    if(column+1 <= sky.at(0).size()-1 && sky.at(row).at(column+1) == 1) { //Look vertically down
        dfs(row, column+1, m_visited, sky);
    }
    if(column-1 >= 0 && sky.at(row).at(column-1) == 1) { //Look vertically up
        dfs(row, column-1, m_visited, sky);
    }
}

我现在被赋予替换
std::vector&lt;std::vector&lt;short&gt;&gt; matrix
的明确任务 与
std::unordered_set&lt;std::vector&lt;size_t&gt;&gt; matrix

我的问题:
size_t 未签名,例如当row = 0(其中行的类型为size_t)时,row -1 未定义,(row -1 &gt; 0)在我的编译器上计算为 true

如何使用size_t 测试row -1 是否仍在我的邻接矩阵的边界内?

【问题讨论】:

  • 你必须测试row &gt; 0
  • “未定义”到底是什么意思?整数重载是为无符号类型完美定义的。与签名不同。
  • 它不是未定义的。通常是下溢,即row - 1 = size_t::max,远高于0
  • 结果肯定不是未定义的。 size_t 是一个无符号整数类型,从 (size_t)0 中减去 (size_t)1 得到一个完全明确的结果,等于 std::numeric_limits&lt;size_t&gt;::max()std::numeric_limits 在标准标头&lt;limits&gt; 中。
  • 数学很简单:row - 1 &gt; 0 &lt;=&gt; row &gt; 1

标签: c++ undefined depth-first-search adjacency-matrix size-t


【解决方案1】:

这是简单的数学运算:row - 1 &gt; 0 &lt;=&gt; row &gt; 1column - 1 &gt; 0 &lt;=&gt; column &gt; 1。你可以替换

if(row-1 >= 0 && sky.at(row-1).at(column) == 1)

if(row >= 1 && sky.at(row-1).at(column) == 1)

if(column-1 >= 0 && sky.at(row).at(column-1) == 1)

if(column >= 1 && sky.at(row).at(column-1) == 1)

你也应该考虑更换

if(row+1 <= sky.size()-1 && sky.at(row+1).at(column) == 1)

if(sky.size() >= 2 && row <= sky.size()-2 && sky.at(row+1).at(column) == 1)

if(column+1 <= sky.at(0).size()-1 && sky.at(row).at(column+1) == 1)

if(sky.at(row).size() >= 2 && column <= sky.at(row).size()-2 && sky.at(row).at(column+1) == 1)

为了避免各种环绕。

【讨论】:

  • 感谢 Thomas - 现在我正在查看它似乎很明显!
  • 整数值永远不会下溢。该术语是为浮点值保留的。并且无符号整数值(正如OP所询问的那样)从定义上永远不会溢出。另外,我不明白这里的数学:row - 1 &gt; 0 &lt;=&gt; row &gt; 1column - 1 &gt; 0 &lt;=&gt; column &gt; 0
  • @IInspectable &lt;=&gt; 是数学等价关系。如果row-1 &gt; 0 然后row &gt; 1 如果row &gt; 1 然后row - 1 &gt; 0。 “column > 0”是一个错字。 std::numeric_limits&lt;unsigned int&gt;::max + 1std::numeric_limits&lt;unsigned int&gt;::min - 1 的正确术语是什么? integer overflow/underflow 和这个问题有什么区别?
  • @IInspectable:不要太直白。 WP: Integer overflow - definition variations and ambiguity 提到整数下溢的“许多引用”。 “环绕”是您可以使用的另一个术语。
  • [basic.fundamental]/2: “无符号算术不会溢出。”
猜你喜欢
  • 1970-01-01
  • 2021-05-14
  • 2023-03-09
  • 2019-09-04
  • 1970-01-01
  • 2019-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
相关资源
最近更新 更多