我的变量“n”是自己递减的,甚至没有提供递减操作,C++ - N_Queen_Problem程序

fkaflof6  于 2023-04-08  发布在  其他
关注(0)|答案(1)|浏览(78)

下面是我创建的NQueen的代码。有一些操作,比如调用nqueen函数,然后从nqueen-〉调用backtrack,它会递归并将值“1”放在动态分配的数组“arr”上。问题是,由于我已经在main中初始化了变量“n”并将其传递到nqueen &从nqueen到backtrack,有时会打印最终创建的完整nqueen数组,“n”被传递给print函数。“n”的值在每个递归调用中都是递减的,在一些递归调用中是这样的,但是我没有提供递减操作。
这是主函数,调用nqueen func传递“n”=4-〉

int main(){
int n=4;
int** arr=new int*[n];
for(int i=0;i<n;i++){
    arr[i]=new int[n];
}
for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
        arr[i][j]=0;
    }
}
print(arr,n);
int num=nqueen(arr, n);
cout<<num<<endl;

return 0;
}

这里是通过传递“arr”和“n”并调用backtrack()传递相同的“arr”和“n”调用的nqueen函数。但是现在n的值以某种方式改变了。

int nqueen(int** arr,int n){
   int count=0;
   for(int i=0;i<n;i++){
     count+=backtrack(arr,i,n);
   }
   return count;
}

这是nqueen调用代码后的backtrack()代码

int backtrack(int** arr,int i,int n){
    if(i==n) return 0;
    int count=0;
    for(int j=0;j<n;j++){
      if(check(arr,i,j,n)==0){
        arr[i][j]=1;
            cout<<"\n"<<i<<" "<<j<<" "<<n<<endl;
            print(arr,n);
        i++;
        count+=backtrack(arr,i,j);
        i--;
        arr[i][j]=0;
       }
     }
    return count;
}

这是包含一些函数的整体代码,如打印和检查数组中的皇后对角线和侧边的“i”和“j”位置

#include<iostream>
using namespace std;

int nqueen(int** arr,int n);
void print(int** arr,int n);
int backtrack(int** arr,int i,int n);
int check(int** arr,int i,int j,int n);

int backtrack(int** arr,int i,int n){
if(i==n) return 0;
int count=0;
for(int j=0;j<n;j++){
    if(check(arr,i,j,n)==0){
        arr[i][j]=1;
            cout<<"\n"<<i<<" "<<j<<" "<<n<<endl;
            print(arr,n);
        i++;
        count+=backtrack(arr,i,j);
        i--;
        arr[i][j]=0;
    }
}
return count;
}

int nqueen(int** arr,int n){
int count=0;
for(int i=0;i<n;i++){
    count+=backtrack(arr,i,n);
}
return count;
}

int check(int** arr, int i,int j,int n){
/////check vertical horizontal
for(int k=0;k<n;k++){
    if(arr[i][k]==1) return 1;
    if(arr[k][j]==1) return 1;
}
/////check diagonal
int k=i,l=j;
while(k<n&&l<n){
    if(arr[k][l]==1){
        return 1;
    }
    k++;
    l++;
}

k=i,l=j;
while(k>=0&&l>=0){
    if(arr[k][l]==1){
        return 1;
    }
    k--;
    l--;
}

k=i,l=j;
while(k>=0&&l<n){
    if(arr[k][l]==1){
        return 1;
    }
    k--;
    l++;
}

k=i,l=j;
while(k<n&&l>=0){
    if(arr[k][l]==1){
        return 1;
    }
    k++;
    l--;
}

return 0;
}

void print(int** arr,int n){
cout<<endl;
for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
        cout<<arr[i][j]<<" "<<i<<j<<" ";
    }
    cout<<endl;
}
}

int main(){
int n=4;
int** arr=new int*[n];
for(int i=0;i<n;i++){
    arr[i]=new int[n];
}
for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
        arr[i][j]=0;
    }
}
print(arr,n);
int num=nqueen(arr, n);
cout<<num<<endl;

return 0;
}

如果有人可以检查并提供我的解决方案。谢谢!

3phpmpom

3phpmpom1#

Jarod42写道:
你调用backtrack(arr,i,j)...所以来自int backtrack(int**arr,int i,int n)的n将是j,但来自main的n不变。
你正在看“n”,这是另一个(=本地)“n”。因为你的递归调用。
但是如果我执行这个,我也会得到一个Segfault。你调用check函数,i的值为“4”。这将访问第行中具有无效偏移量的arr:

if(arr[i][k]==1) return 1;

对于大小为4的数组,有效值仅从0到3。编辑:当然i是4,因为在递归调用之前,有i++,如果它被允许变得更高,没有任何检查。我真的不明白这段代码的目的是什么,所以也许检查i和j是否有效就足够了,如果不是,就停止。

相关问题