0

イントロ プログラムでは、指定されたサイズの有効な魔方陣をすべて見つけることができるプログラムを作成するように依頼されました。再帰関数内からクラス変数を変更するのに問題があります。私が試みている数字の組み合わせが魔方陣を生み出すたびに、見つかった魔方陣の数を増やしようとしています。

より具体的には、関数 recursiveMagic() 内で numSquares を変更しようとしています。その特定の行にブレークポイントを設定した後、変数 numSquares はインクリメントしても変化しません。再帰と関係があると思いますが、よくわかりません。アドバイスをいただければ幸いです。

//============================================================================
// Name        : magicSquare.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;

/**
 * MagicSquare
 */
class MagicSquare {
private:
    int magicSquare[9];
    int usedNumbers[9];
    int numSquares;
    int N;
    int magicInt;
public:

    MagicSquare() {
        numSquares = 0;
        for (int i = 0; i < 9; i++)
            usedNumbers[i] = 0;
        N = 3; //default is 3
        magicInt = N * (N * N + 1) / 2;
    }

    MagicSquare(int n) {
        numSquares = 0;
        for (int i = 0; i < 9; i++)
            usedNumbers[i] = 0;
        N = n;
        magicInt = N * (N * N + 1) / 2;
    }

    void recursiveMagic(int n) {
        for (int i = 1; i <= N * N + 1; i++) {
            if (usedNumbers[i - 1] == 0) {
                usedNumbers[i - 1] = 1;
                magicSquare[n] = i;
                if (n < N * N)
                    recursiveMagic(n + 1);
                else {
                    if (isMagicSquare()) {
                        numSquares++; //this is the line that is not working correctly
                        printSquare();
                    }
                }
                usedNumbers[i - 1] = 0;
            }
        }
    }
    //To efficiently check all rows and collumns, we must convert the one dimensional array into a 2d array
    //since the sudo 2d array looks like this:
    //        0 1 2
    //        3 4 5
    //        6 7 8
    //the following for-if loops convert the i to the appropriate location.

    bool isMagicSquare() {
        for (int i = 0; i < 3; i++) {
            if ((magicSquare[i * 3] + magicSquare[i * 3 + 1] + magicSquare[i * 3 + 2]) != magicInt) //check horizontal
                return false;
            else if ((magicSquare[i] + magicSquare[i + 3] + magicSquare[i + 6]) != magicInt) // check vertical
                return false;
        }
        if ((magicSquare[0] + magicSquare[4] + magicSquare[8]) != magicInt)
            return false;
        if ((magicSquare[6] + magicSquare[4] + magicSquare[2]) != magicInt)
            return false;
        return true;
    }

    /**
     * printSquare: prints the current magic square combination
     */
    void printSquare() {
        for (int i = 0; i < 3; i++)
            cout << magicSquare[i * 3] << " " << magicSquare[i * 3 + 1]
                << " " << magicSquare[i * 3 + 2] << endl;
        cout << "------------------" << endl;
    }

    /**
     * checkRow: checks to see if the current row will complete the magic square
     * @param i - used to determine what row is being analyzed
     * @return true if it is a working row, and false if it is not
     */
    bool checkRow(int i) {
        i = (i + 1) % 3 - 1;
        return (magicSquare[i * 3] + magicSquare[i * 3 + 1] + magicSquare[i * 3 + 2]) == magicInt;
    }

    int getnumSquares() {
        return numSquares;
    }
}; //------End of MagicSquare Class-----

int main() {
    MagicSquare square;
    cout << "Begin Magic Square recursion:" << endl << "------------------"
            << endl;
    square.recursiveMagic(0);
    cout << "Done with routine, returned combinations: " << square.getnumSquares() << endl;
    return 0;
}
4

1 に答える 1

1

配列が上書きされ、numSquares フィールドが上書きされています。

class MagicSquare {
private:
    int magicSquare[9];
    int usedNumbers[9];

への変更

class MagicSquare {
private:
    int magicSquare[10];
    int usedNumbers[10];

また、イニシャライザでは、ループは < 9 と言いますが、言いたいことは < 10 です。または、その目的には memset を使用する方が適切です。

于 2013-02-18T00:55:39.740 に答える