簡體   English   中英

C語言isMagicsquare函數:函數代碼中有什么邏輯錯誤?

[英]C language isMagicsquare function: What logic error is in my function code?

盡管當前示例的輸出是正確的,但是我的代碼似乎存在邏輯錯誤,無法為其他情況提供正確的輸出。

我之前已經解決了這個問題:

“如果沒有重復的數字,使用了所有數字,最后一列的總和是正確的,但是倒數第二列的總和不正確,那么在代碼中會發生什么?”

任何幫助將不勝感激。

我當前的代碼:

/* Magic Square */
#include <stdio.h>

#define MAX_N 100
#define TRUE  1
#define FALSE 0

int isMagicSquare(int square[MAX_N][MAX_N], int n);

int main(void) {
    int square1[MAX_N][MAX_N] = {
            {4, 9, 2},
            {3, 5, 7},
            {8, 1, 6}};

    // should print TRUE
    int check1 = isMagicSquare(square1, 3);
    if (check1 == TRUE) {
        printf("TRUE\n");
    } else {
        printf("FALSE\n");
    }

    int square2[MAX_N][MAX_N] = {
            {20,  6,  7, 17},
            { 9, 15, 14, 12},
            {13, 11, 10, 16},
            { 8, 18, 19, 5} };

            /*{ 1 , 2 , 3 , 4 , },
            { 5 , 6 , 7 , 8 , },
            { 9 , 10, 11, 12, },
            { 13, 14, 15, 16,} };*/

            /*{16, 2, 3, 13,}, 
            {5, 11, 10, 8 ,},
            {9,  7, 6, 12 ,},
            {4, 14, 15, 1, } };*/ 

    // should print FALSE
    int check2 = isMagicSquare(square2, 4);
    if (check2 == TRUE) {
        printf("TRUE\n");
    } else {
        printf("FALSE\n");
    }

    int square3[MAX_N][MAX_N] = {
            {17, 24,  1, 15,  8},
            {23,  5,  7, 16, 14},
            { 4,  6, 13, 22, 20},
            {10, 12, 19,  3, 21}, 
            {11, 18, 25,  9,  2}};

    // should print FALSE
    int check3 = isMagicSquare(square3, 5);
    if (check3 == TRUE) {
        printf("TRUE\n");
    } else {
        printf("FALSE\n");
    }

    return 0;
}

int isMagicSquare(int square[MAX_N][MAX_N], int n) {
    int row, col;
    int drow, dcol;
    int sum, sum1, sum2, sum3;
    int boolean = 0;

    //For Diagonals
    sum = 0;
    for (row = 0; row < n; row++) {
        for (col = 0; col < n; col++) {
            if (row == col)
                sum += square[row][col];
        }
    }

    for (row = 0; row < n; row++) {
        sum3 = 0;
        for (col = 0; col < n; col++) {
            sum3 += square[n-row-1][col]; 
        }
        if (sum == sum3)
            boolean = 1;
        else {
            return FALSE;
        }
    }

    //For Rows
    for (row = 0; row < n; row++) {
        sum1 = 0;
        for (col = 0; col < n; col++) {
            sum1 = sum1 + square[row][col];
        }
        if (sum == sum1)
            boolean = 1;
        else {
            return FALSE;
        }
    }

    //For Columns
    for (row = 0; row < n; row++) {
        sum2 = 0;
        for (col = 0; col < n; col++) {
            sum2 = sum2 + square[col][row];
        }
        if (sum == sum2)
            boolean = 1;
        else {
            return FALSE;
        }
    }

    if (boolean == 1) {
        //Check if All Numbers is used

        for (row = 0; row < n; row++) {
            for (col = 0; col < n; col++) {
                if(square[row][col] > n*n || square[row][col] < 0) {
                    boolean = 0;
                    break;
                }
            }
        }

        //Check for Repeating Numbers
        for (row = 0; row < n; row++) {
            for(col = 0; col < n; col++) {

                for(drow = row + 1; drow < n; drow++){
                    for(dcol = col + 1; dcol < n; dcol++) {
                        if(square[row][col] == square[drow][dcol]) {
                            boolean = 0;
                            break;
                        }
                    }   
                }
            }
        }
        // if Statement End
    }
    else {
        boolean = 0;
    }

    if (boolean == 1)
        return TRUE;
    else
        return FALSE;
}

看來sum3 var在計算循環內重新初始化為0,加上對角線和相等檢查應該在循環外。

我會這樣修改:

//For Diagonals
sum = 0;
sum3 = 0;
for (row = 0; row < n; row++) {
    sum  += square[row][row];
    sum3 += square[row][n - 1 - row];
}
if (sum == sum3)
    boolean = 1;
else {
    return FALSE;
}

順便說一句,由於它是線性的,所以我對角線的計算進行了一些簡化,不需要2個嵌套循環。

我在最終檢查中發現了一些其他錯誤:

-0應該不是有效值

-return而不僅僅是中斷(break僅存在於內部循環中,外部循環繼續)

for (row = 0; row < n; row++) {
    for (col = 0; col < n; col++) {
        if(square[row][col] > n*n || square[row][col] <= 0) {
            return FALSE;
        }
    }
}

//Check for Repeating Numbers
int storedNumbers[n * n];
for (row = 0; row < n; row++) {
    for(col = 0; col < n; col++) {
        storedNumbers[row + n * col] = square[row][col];
    }
}

然后掃描storedNumbers是否重復。 在數組中搜索重復值

干杯

您可以使用更緊湊的方案來檢查所有數字1 .. (n*n)是否使用重復的代碼,例如:

int counts[n * n];  // Can't use an initializer with a VLA
memset(counts, '\0', sizeof(counts));

for (int i = 0; i < n; i++)
{
    for (int j = 0; j < n; j++)
    {
        if (square[i][j] <= 0 || square[i][j] > n * n)
            return FALSE;
        counts[square[i][j] - 1]++;  // Map 1..n*n to 0..n*n-1
        // if (++counts[square[i][j] - 1] > 1)
        //     return FALSE;
    }
}

for (int i = 0; i < n * n; i++)
{
    if (counts[i] != 1)
        return FALSE;
}

由於要檢查n*n元素,因此此代碼使用的空間和時間相對於幻方中的元素數量是線性的,這在最佳常數因子之內。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM