簡體   English   中英

根據二維數組的內容檢查值

[英]Check values against contents of 2D array

我正在嘗試遍歷類型為 Cell Cell m_grid[9][9]的二維數組 - 當數組中的當前值不等於數組的行、列或 3x3 塊中的值時,我需要將其添加到我的int m_candidateList[9]數組中。 二維數組本身包含一個 9x9 格式的未解決的數獨游戲。

如何訪問二維數組的行和列,以便我可以根據數組在循環中的當前值檢查它們?

這是在我的 SudokuPuzzle.cpp 文件中,我想在其中獲取當前拼圖值,並根據數獨拼圖的該行、列和 3x3 塊中的所有值檢查它。

for (int i = 0; i < 9; i++)
{
    for (int j = 0; j < 9; j++)
    {
            
        //if number doesn't appear in row
        //if number doesn't appear in col
        //if number doesn't appear in 3x3
        //add number to candidate list
        
    }
}

我的 Cell.cpp 包含拼圖中每個單獨值的數據成員

Cell::Cell(void) {}
Cell::~Cell(void) {}

void Cell::SetValue(int value)
{
    m_value = value;

    if (m_value = 0)
    {
        m_given = true;
    }
}

和 Cell.h

#pragma once
class Cell
{
public:
    Cell(void);
    ~Cell(void);

    void SetValue(int n);

private:

    int m_candidateList[9];
    int m_value;
    bool m_given;

};

所以我將嘗試概述邏輯。 我將忽略Cell class,因為我沒有它的完整詳細信息,我只是假設您的網格是一個整數數組。

真正重要的是將一段相當復雜的代碼分解成單獨的函數。 這將使代碼更容易編寫、更容易調試和更容易理解。

這是我的看法,僅供參考

for (int row = 0; row < 9; row++)
{
    for (int col = 0; col < 9; col++)
    {
        for (int number = 1; number <= 9; number++)
        {
            if (!number_in_row(number, row) &&
                !number_in_column(number, col) &&
                !number_in_square(number, row, col))
            {
                 add_number_to_candidates(number, row, col);
            }
        }
    }
}

bool number_in_row(int number, int row)
{
     for (int col = 0; col < 9; ++col)
          if (m_grid[row][col] == number)
              return true;
     return false;
}

Function number_in_column非常相似。 Number_in_square是最復雜的一個。

bool number_in_square(int number, int row, int col)
{
    // calculate start of 3x3 square
    int row_start = 3*(row/3);
    int col_start = 3*(col/3);
    for (int r = 0; r < 3; ++r)
        for (int c = 0; c < 3; ++c)
          if (m_grid[row_start + r][col_start + c] == number)
              return true;
    return false;
}

我遺漏了add_number_to_candidates function,因為我不確定如何使用給定的信息來寫它。 希望你會清楚。

我希望這能給你一些想法。 所有代碼完全未經測試。

此答案的大部分內容僅取自發表評論的用戶。

我可以看到你有一個 setter function SetValue(int n) 但是為了能夠訪問你已經存儲的內容,你還需要一個 setter function 這樣你就可以調用你的 Cell object 並可以訪問這個價值。 我們稱此設置器為 function getValue()。

請注意,getValue 返回 boolean,但可以為通過引用傳遞的 int 賦值。 這允許我們使用 getValue function 做兩件事,首先它檢查一個值是否已分配給此單元格,其次如果該值已分配,則您通過傳遞引用的變量將其傳回。

細胞.cpp

Cell::Cell(void) {}
Cell::~Cell(void) {}

void Cell::SetValue(int value)
{
    m_value = value;

    if (m_value = 0)
    {
        m_given = true;
    }
}

bool Cell::getValue(int& n)
{
    if(m_given)
        n = m_value;

    return m_given;
}

void Cell::insertCandidate(int n)
{
    m_candidateList[m_candidate_counter++] = n;
}

細胞.h

#pragma once
class Cell
{
public:
    Cell(void);
    ~Cell(void);

    void SetValue(int n);
    bool getValue(int& n);

    void insertCandidate(int n);

private:

    int m_candidate_counter = 0;
    int m_candidateList[9];
    int m_value;
    bool m_given;

};

現在使用 getter,您可以循環遍歷 2d 單元格數組,因為您現在有一個 getter function。

數獨謎題.cpp

for (int i = 0; i < 9; i++)
{
    for (int j = 0; j < 9; j++)
    {
        for (int number = 1; number <= 9; number++)
        {
            if(!exists_in_row(number, i) && 
               !exists_in_column(number, j) && 
               !exists_in_square(number, i, j))
            {
                m_grid[i][j].insertCandidate(number);
                return;
            }
        }
    }
}

您還需要創建輔助函數。 例如在 SudokuPuzzle.cpp 中

bool SudokuPuzzle::exists_in_row(int number, int row)
{
    int number_from_cell = 0;

    for (int col = 0; col < 9; ++col)
    {        
        if(m_grid[row][col].GetValue(number_from_cell) && number_from_cell == number)
             return true;
    }
    return false;
}

bool SudokuPuzzle::exists_in_column(int number, int col)
{
    int number_from_cell = 0;
    
    for (int row = 0; row < 9; ++row)
    {       
        if(m_grid[row][col].GetValue(number_from_cell) && number_from_cell == number)
             return true;
    }
    return false;
}

bool SudokuPuzzle::exists_in_square(int number, int row, int col)
{
    int row_start = 3*(row/3);
    int col_start = 3*(col/3);
    int number_from_cell = 0;

    for (int r = 0; r < 3; ++r)
    {
        for (int c = 0; c < 3; ++c)
        {
            if (m_grid[row][col].GetValue(number_from_cell) && number_from_cell == number)
              return true;
        }
    }
    return false;
}

此外,通過創建單元格 object 並擁有二維單元格陣列,您的生活也會變得有些困難。 如果您只使用類型 int m_grip[9][9],答案可能會更直接。 同樣對於 m_candiateList,我沒有對此數據類型進行任何更改,但請查看 std::set 以避免存儲重復項並避免 memory 問題。 例如,假設您沒有添加保護代碼而您嘗試訪問 m_candidateList[10],這會給您帶來分段錯誤。

暫無
暫無

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

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