根据2D数组的内容检查值

时间:2020-07-28 19:15:38

标签: c++ arrays

我正在尝试遍历单元格return类型的2D数组-当数组中的当前值不等于数组的行,列或3x3块中的值时,我需要将其添加到我的Cell m_grid[9][9]数组中。 2D阵列本身包含一个9x9格式的未解决的数独难题。

如何访问2D数组的行和列,以便可以根据数组在循环中的当前值检查它们?

这是在我的SudokuPuzzle.cpp文件中,我想在其中获取当前的拼图值并将其与数独拼图的该行,列和3x3块中的所有值进行比较。

int m_candidateList[9]

My Cell.cpp,其中包含谜题中每个单独值的数据成员

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.h

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

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

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

2 个答案:

答案 0 :(得分:2)

因此,我将尝试概述逻辑。我将忽略Cell类,因为我没有它的全部详细信息,而我只是假设您的网格是一个整数数组。

真正重要的是将相当复杂的代码片段分解为单独的函数。这将使代码更易于编写,调试和理解。

这是我的看法,只有建议

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

功能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函数。希望你会明白的。

我希望能给您一些想法。所有代码都未经测试。

答案 1 :(得分:1)

大部分答案仅来自发表评论的用户。

我可以看到您有一个setter函数SetValue(int n),但是要能够访问您已经存储的内容,那么您还需要一个setter函数,以便可以调用Cell对象并具有获取此值。我们将此设置函数称为getValue()。

请注意,getValue返回一个布尔值,但可以为通过引用传递的int分配一个值。这使我们可以使用getValue函数执行两件事,首先,它检查是否已为该Cell分配了一个值,其次,如果已分配了该值,则可以通过传递引用的变量将其传递回去。

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

Cell.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;

};

现在,使用吸气剂,您现在就可以遍历二维单元格数组,因为现在有了吸气剂功能。

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

另外,通过创建Cell对象并具有2D Cells数组,您的生活也有些困难。如果您只是使用int m_grip [9] [9]类型,答案可能会更直接。同样对于m_candiateList,我没有对此数据类型进行任何更改,但请查看std :: set以避免存储重复项,也避免了内存问题。例如。想象一下,您没有添加保护代码,而是尝试访问m_candidateList [10],这将给您带来分段错误。