【问题标题】:How would one see if an array has consecutive numbers in C++?在 C++ 中如何查看一个数组是否有连续的数字?
【发布时间】:2013-03-03 17:38:29
【问题描述】:

这基本上是 8 个皇后问题,但是在一维数组中用蛮力解决它。假设我有一个大小为 8 的数组(名为 b),其元素范围为 0 到 7。

我用 8 个 for 循环初始化数组中的每个索引,如下所示:

int b[8]={0};

int count = 0;


for(b[0] = 0; b[0]<8; b[0]++){ 
for(b[1] = 0; b[1]<8; b[1]++){ 
for(b[2] = 0; b[2]<8; b[2]++){ 
for(b[3] = 0; b[3]<8; b[3]++){ 
for(b[4] = 0; b[4]<8; b[4]++){ 
for(b[5] = 0; b[5]<8; b[5]++){
for(b[6] = 0; b[6]<8; b[6]++){
for(b[7] = 0; b[7]<8; b[7]++){
                if(check(b)) 
                {
                count++;
                print(b, count);
                }
            }}
        }}
    }}
}}

这个程序应该做的是检查数字 0 到 7 的每个组合,并仅在某些条件下返回 true。应该有 92 个解决方案,如果这听起来很熟悉,应该是 - 这是使用蛮力的 8 个皇后问题。从这里,这是我理解的条件:

我希望能够检查一个数组是否有连续的数字串;如:

[0|5|7|1|2|3|6|4]

这里,元素b[3]、b[4]和b[5]是连续的。我不想这样,我想返回false,因为有一串连续的数字(基本上是皇后在攻击)

我也不想要一个包含一串向后连续数字的数组,如下所示:

[0|5|7|3|2|1|6|4]

最后,我不希望索引中有两个或多个数字,如果我们简单地更改它们之间的数字,这会使它们看起来连续:

[0|2|4|6|1|3|5|7]

以上是不可接受的,因为 b[0] 和 b[7] 是它们“连续索引”中的数字(因为至少有 2 个皇后在互相攻击)。

[6|1|3|0|4|7|5|2]

上述也是不可接受的,因为 b[1] 和 b[4] 也在连续的索引中。

同样,当交换值时,数组

[7|2|4|6|1|3|5|0]

[6|4|3|0​​|1|7|5|2]

也是不可接受的。我也不能有 2 个或更多相同的数字。

我遇到的问题是创建检查功能。我被告知我需要使用 1 个 for 循环和 1 个 if-then 语句。检查功能可以按原样获取整个数组吗?如果是这样,如何查看数组中最右边的元素,并检查它是否有连续的索引(皇后正在攻击它)?我试过这个:

bool ok(int board[8]){

    for(int c = 7; c >= 0; c--){ //row check
        for (int j=0; j<c; j++){
            if (board[c]==board[j]){
                return false;
            }
        }


        for(int i = 1; i <= c; i++){
            // diagonal check from top left to bottom right
            if  ((board[c]-i >= 0) && (board[c-i] == board[c]-i))
                {return false;}
            if ((board[c]+i <= 7) && (board[c+i] == board[c]+i))
                {return false;}
            // diagonal check from bottom left to top right
            if ((board[c]-i >= 0) && (board[c-i] == board[c]+i))
                {return false;}
            if ((board[c]+i <= 7) && (board[c+i] == board[c]-i))
                {return false;}

        }

    }

    return true;
}

但这不仅不起作用(我得到了 300 多个解决方案),而且它也没有我听说的那么小。

【问题讨论】:

    标签: c++ arrays function n-queens


    【解决方案1】:

    我认为您检查对角线中的碰撞有一个小问题:您有 15 条对角线每条路(包括角落中非常短的方形对角线),而您的代码只检查每条中的 7 条由于board[c]+i &lt;= 7board[c]-i &gt;= 0 条件。

    以下是使用三个布尔数组简化检查并使其更快的方法:您有 8 行、15 条上升对角线和 15 条下降对角线:

    bool row[8];
    bool ascending[15];
    bool descending[15];
    

    最初,这些行/对角线中没有皇后。当您浏览board 的元素时,请执行以下操作:

    for (int i = 0 ; i != 8 ; i++) {
        // Check and mark the row
        if (row[board[i]]) return false;
        row[board[i]] = true;
        // Check and mark the ascending diagonal
        int ascIdx = board[i]+i;
        if (ascending[ascIdx]) return false;
        ascending[ascIdx] = true;
        int descIdx = 7+board[i]-i;
        if (descending[descIdx]) return false;
        descending[descIdx] = true;
    }
    return true;
    

    【讨论】:

    • 对不起,我对 bool 数组不熟悉(甚至不知道它们存在),你能澄清一下“if (row[board[i]]) return false;”到底是什么吗?完成?我知道它是在检查条件的真值,但它检查真假的目的是什么?
    • @Chase 正如您猜对的那样,布尔数组存储布尔值(truefalse)。最初需要将数组设置为false,因为bool 是原始类型(我没有在答案中显示此代码,但本质上您需要一个循环将数组的每个元素设置为false)。当您访问特定索引处的元素时,您将取回存储在那里的最后一个值。上面if 条件中发生的情况本质上是一种检查“我之前是否将同一元素中的值设置为true”。
    • 谢谢,这真的很有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    • 2016-04-27
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    相关资源
    最近更新 更多