Моя переменная "n" сама по себе уменьшается, даже не предоставляя операции уменьшения. Программа C ++ - N_Queen_Problem - PullRequest
0 голосов
/ 13 марта 2020

Вот код для NQueen, который я создал. Есть несколько операций, таких как вызов функции nqueen, затем из nqueen-> callback back, который выполняет рекурсию и помещает значение «1» в динамически размещенный массив «arr». Проблема в том, что, поскольку я инициализировал переменную «n» в main и передал в nqueen & из nqueen в backtrack, а иногда для печати окончательно созданного полного массива nqueen, «n» передается в функцию print. Значение "n" уменьшается в каждом рекурсивном вызове, а в некоторых из них, но я не предоставил никакой операции уменьшения.

это основной вызов nqueen fun c, передавая "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;
}

- это функция nqueen, вызываемая передачей« arr »и« n »и вызывающая backtrack () с передачей тех же« arr »и« n ». но теперь значение n как-то меняется.

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

это код backtrack () после nqueen вызывает код

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;
}

это общий код с некоторыми функциями, такими как print и проверим массив для королев по диагонали и сбоку для этой позиции "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;
}

, если кто-то может проверить это и предоставить мне решение для этого. Спасибо!

1 Ответ

2 голосов
/ 13 марта 2020

Как писал Jarod42:

Вы вызываете backtrack (arr, i, j) ... Так что n из int backtrack (int ** arr, int i, int n) будет таким, что j , но n из main не изменилось.

Вы смотрите "n", которое является другим (= локальным) "n". Из-за вашего рекурсивного вызова.

Но я также получаю Segfault, если выполню это. Вы вызываете функцию проверки со значением «4» для i. Это получит доступ к arr с недопустимым смещением в строке:

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

Только допустимые значения go от 0 до 3 для массива размера 4. EDIT: конечно, i равно 4, потому что перед рекурсивным вызовом made is i++ без какой-либо проверки, если это становится выше, чем это разрешено. Я не совсем понимаю, для чего предназначен этот код, поэтому, возможно, достаточно проверить, действительны ли значения i и j, и остановить, если нет.

...