繁体   English   中英

如何看待一个数组在C ++中是否具有连续的数字?

[英]How would one see if an array has consecutive numbers in C++?

这基本上是8 Queens问题,但在一维数组中用蛮力解决。 假设我有一个大小为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进行循环,并使用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多个解决方案),而且还没有告诉我那么小。

我认为检查对角线中的碰撞存在一点问题:每种方式有15条对角线(包括拐角处非常短的一平方对角线),而由于board[c]+i <= 7并且board[c]-i >= 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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM