zoukankan      html  css  js  c++  java
  • 软件工程第二次作业——数独

    1. 项目需求:利用程序随机构造N个已解答的数独棋盘 

    2. 输入:数独棋盘题目个数N (0 < N <= 1000000)

    3. 输出:随机生成N个不重复的已解答完毕的数独棋盘, 并输出到sudotiku.txt,每个数独棋盘中间隔一行

                  可执行文件exe,用法:(sudotiku.exe -c 20)(其中20为题目个数)

    头文件sudoku.h:

    #ifndef SUDOKU_H
    #define SUDOKU_H

    bool Sudoku_Row(int sudo[9][9], int row, int num);
    bool Sudoku_Col(int sudo[9][9], int col, int num);
    bool Sudoku_Square(int sudo[9][9], int row, int col, int num);
    void print_sudoku(int sudo[9][9]);
    bool makeSquare(int sudo[9][9], int num);

    #endif

    源程序:

    #include "pch.h"
    #include <iostream>
    #include <ctime>
    #include <fstream>
    #include <stdlib.h>
    #include "sudoku.h"
    using namespace std;
    #define Random(x) (rand()%x)
    bool flag = false;

    void Init_sudo(int(*sudo)[9])
    {
    for(int r=0;r<9;r++)
       {
           for (int c = 0; c < 9; c++)
           sudo[r][c] = 0;
       }
      sudo[0][0] = 1;//初始化数独,使第一个数为1
    }
    void Init_sudo_part(int(*sudo)[9])
    {
         for (int r = 3; r < 9; r++)
        {
           for (int c = 0; c < 9; c++)
           sudo[r][c] = 0;
         }
        for (int r = 0; r < 3; r++)
        {
           for (int c = 3; c < 9; c++)
           sudo[r][c] = 0;
        }
    }
    bool check_sudo(int sudo[9])
    {
         int temp;
         for (int i = 0; i < 9; i++)
        {
           temp = sudo[i];
           for (int j = i + 1;j < 9; j++)
             {
                  if (sudo[j] == temp)
                  return false;
             }
         }
    return true;
    }
    //行检查
    bool Sudoku_Row(int sudo[9][9], int row, int num)
    {
         bool flag = false;//冲突标志
         for (int i = 0; i < 9; i++)
           {
              if (sudo[row][i] == num)
              {
                 flag = true;
                 break;
              }
           }
    return flag;
    }
    //列检查
    bool Sudoku_Col(int sudo[9][9], int col, int num)
    {
          bool flag = false;
         for (int i = 0; i < 9; i++)
         {
             if (sudo[i][col] == num)
             {
                 flag = true;
                 break;
              }
          }
    return flag;
    }
    //宫检查
    bool Sudoku_Square(int sudo[9][9], int row,int col, int num)
    {
          bool flag = false;
          int Square_Row = row / 3 * 3;
          int Square_col = col / 3 * 3;
          for (int i = 0; i < 3; i++)
         {
            for (int j = 0; j < 3; j++)
              {

                  if (sudo[Square_Row+i][Square_col+j] == num)
                  {
                       flag = true;
                       break;
                  }
              }
         }
    return flag;
    }
    void print_sudoku(int sudo[9][9])
    {
         for (int i = 0; i < 9; i++)
         {
             for (int j = 0; j < 9; j++)
             {
                  cout << sudo[i][j] << ' ';
             }
            cout << endl;
        }
        cout << endl;
    }
    //生成宫格
    bool makeSquare(int sudo[9][9], int num)
    {
         int square_row = (num / 3) * 3;
         int square_col = (num % 3) * 3;
         int x, y;
         int temp;
         if (num = 0) //第一个宫格
        {
           for (int i = 1; i < 9; i++)
           {
              x = square_row + i / 3;
              y = square_col + i % 3;
             temp = Random(8) + 2;//生成2~9的随机数
             if (!Sudoku_Square(sudo, x, y, temp) && !Sudoku_Col(sudo,
    y, temp) && !Sudoku_Row(sudo, x, temp))
             {
               sudo[x][y] = temp;
             }
             else i--;
           }
       }
    else //生成其他宫格
     {
          int try_count = 0;
          temp = Random(9) + 1;//生成1~9的随机数
          for (int i = 0; i < 9; i++)
         {
              x = square_row + i / 3;
              y = square_col + i % 3;
              temp++;
              temp = temp % 10;//循环随机数在1~9范围内
              if (!Sudoku_Square(sudo, x, y, temp) && !Sudoku_Col(sudo,
              y, temp) && !Sudoku_Row(sudo, x, temp) && temp != 0)
              {
                   sudo[x][y] = temp;
                   try_count = 0;
               }
              else
              {
                    i--;
                    try_count++;
               }
              if (try_count > 10)
              {
                    return false;
                    break;
               }//若所有可能试完则返回无解
        }

     }
    return true;//有解
    }
    int main(int argc, char *argv[])
    {
         int N = atoi(argv[argc-1]);
         int(*sudo)[9] = new int[9][9];
         ofstream outfile;
         outfile.open("sudoku.text");//输出到文档
         if (N > 0 && N <= 1000000)
         {
             srand(unsigned int(time(NULL)));//初始化种子为当前时间
             bool retry;//重试
             int retry_count = 0;//重试次数
             for (int i = 0; i < N;)
            {
               retry = false;
               if (retry_count == 0)
               {
                   Init_sudo(sudo);
                   makeSquare(sudo, 0);
               }
              else Init_sudo_part(sudo);
              for (int j = 1; j < 9; j++)
              {
                   bool flag = makeSquare(sudo, j);
                   if (!flag)
                   {
                        retry = true;
                        break;
                   }
               }
              if (!retry)
             {
                  for (int row = 0; row < 9; row++)
                  {
                       for (int col = 0; col < 9; col++)
                       {
                           outfile << sudo[row][col] << ' ';
                        }
                   outfile << endl;
                  }//输出一个数独矩阵
              outfile << endl;
              retry_count = 0;
              i++;
           }
         else
        {
            retry_count++;
         }//无解重试
       }
      outfile.close();
     }
    else cout << "please input a proper number:" << endl;
    return 0;
    }

    输出到sudoku.txt中:

    程序分析:输出和生成宫格所用的时间比较多,还有待完善改进,但生成的数独没有重复的。这次项目我耗时比较长,也查了许多资料和百度参考别人的经验。我用的是VS2017版本,在调试过程需要在头文件加#include "pch.h"。

    心得体会:通过这次作业,我发现我存在了很多有关于算法和编程方面的不足,程序中一点细微的问题都要处理比较久,但值得开心的是学到了一些知识,以后要加强算法和编程方面的练习。

    课外任务:大一学过一点C语言,现在正在自学C++,目前能够看懂一些比较基础的程序代码和编写一些简单的程序,算法是个薄弱环节,距离一个合格的IT专业毕业生还有很大的差距,需要提高算法能力和编程能力,还有优化代码的能力。以下这个表是我目前的技能水平和期待课程结束后能达到的水平:

  • 相关阅读:
    java中4种修饰符访问权限的区别
    Java中List的排序方法
    Hibernate事务
    @Component、@Service、@Constroller
    MySQL查看一个表的创建文本以及删除表某列的索引
    深入Session2
    Tomcat容器的Session管理
    深入Session
    使用spring mvc或者resteasy构建restful服务
    Spring MVC学习回顾
  • 原文地址:https://www.cnblogs.com/muyang2/p/9751411.html
Copyright © 2011-2022 走看看