软件工程实践2019第三次作业

软件工程实践2019第三次作业

Gethub项目地址:

https://github.com/liuxinyao0722

PSP表格:

PSP2.1 Personal Software Process Stages 预估耗时(小时) 实际耗时(小时)
Planning 计划 1h 1h
Estimate 估计这个任务需要多少时间 21h 20h
Development 开发 3h 3h
Analysis 需求分析 (包括学习新技术) 2h 2.5h
Design Spec 生成设计文档 2h 1.5h
Design Review 设计复审 0.5h 0.5h
Coding Standard 代码规范 (为目前的开发制定合适的规范) 2h 2h
Design 具体设计 3h 2.5h
Coding 具体编码 1h 1h
Code Review 代码复审 1h 0.5h
Test 测试(自我测试,修改代码,提交修改) 3h 2.5h
Reporting 报告 1h 1h
Test Repor 测试报告 0.5h 0.5h
Size Measurement 计算工作量 1h 1h
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 1h 1h
合计 22h 20.5h

解题思路

一开始在看到题目的时候,因为之前玩过数独,大家基本思路都一样,填入数独初步的思路是设计2~3个函数,一两个函数判断行或列数字是否重复,一个函数判断宫中的数字是否重复(4,6,8,9需要判断宫的数字),然后如果重复了怎么填入数字,一开始没有思路,借鉴了几篇博客后,想起了回溯遍历DFS的方法,所以思路大概是输入文件 填数 判断重复 回溯 输出文件这几部分。其中,填数和判断重复反复回溯判断。

函数:数独清空重置

void memset(){ //初始化数独数组
   for(i=0;i<9;i++) 
   for(j=0;j<9;j++){
   sudu[i][j]=0;
   }
} 

行列重复判断函数

bool hanglie(int x, int w)//验证行与列,宫格为4 6 8 9的时候需要判断宫 
{
    int row= x/m;
    int column=x%m;
    for (int i=0;i<m;i++)//行 
    {
        if (sudu[row][i]== w) 
		{ return 0; }
    }
    for (int i=0;i<m;i++)//列 
    {
        if (sudu[i][column] == w) 
		{return 0;}
    }
    if (m==4)//4宫格
    {
        if (gong(x,2,2,w))  {return 1;}
        else{return 0;   }
    }
    else if (m==6)//6宫格
    {
        if (gong(x,2,3,w)) { return 1;}
        else  {return 0;}
    } 
    else if (m==8)//8宫格
    {
        if (gong(x,4,2,w)) {return 1;}
        else {return 0;}
    }
    else if (m==9)//9宫格
    {
        if (gong(x,3,3,w)) {return 1;}
        else {return 0;}
    }
    return 1;
}

宫的重复判断

bool gong(int x,int row,int column,int w)//判断宫 
{   int a,b;
    a=x/m;b=x%m;
    a=a/row*row;//行
    b=b/column*column;//列
    for (int i=a;i<a+row;i++)
    {  for (int j=b;j<b+column;j++)
        {  if (sudu[i][j] == w)
             { return 0; }  
        }
    }
    return 1;
}

DFS函数

void DFS(int x)//回溯遍历 
{ int row,column;//定义行和列 
   if (finish)//若已完成 直接返回 
     {return;}
    if (x==m*m)//已经找完 输出返回 
    {   output();
        finish = 1;
        return;
    }
  row= x/m;//行
  column=x%m;//列
    if (!sudu[row][column])//位置为空则填入数字 
    { for (int i=1;i<=m;i++)
        { if (hanglie(x,i))
            { sudu[row][column] = i;
                DFS(x+1);
                sudu[row][column] = 0;//回溯 
            }
        }
    }
    else//有数字则跳过 
    { DFS(x+1);}
}

输出函数

void output()//输出
{ for (i=0;i<m;i++)
  {for (j=0;j<m;j++)
    { fprintf(fpout,"%d",sudu[i][j]);//打印到输出文件
       if (j<m-1)//非行末都要加空格 
         {
		  fprintf(fpout, " ");  
	     }
    }
   fprintf(fpout, "\n");//每行结束换行 
  }
}

主函数

int main(int argc, char *argv[])
{   m=atoi(argv[2]);//宫格数 
    n=atoi(argv[4]);//盘数 
    char *inname = argv[6];//输入文件名 
    char *outname = argv[8];//输出文件名 
    fpin = fopen(inname, "r");//打开输入文件
    if (fpin==NULL) {
	return -1;}
    fpout = fopen(outname,"w");//打开输出文件
    if (fpout==NULL) {
	return -1;}
	fclose(fpout);//关闭输出文件 
    while(n--)//当盘数非0循环 
    {   finish = 0;
	   memset();//初始化 置零  
        for(int i=0;i<m;i++)
        { for(int j=0;j<m;j++)
            {fscanf(fpin,"%d",&sudu[i][j]);}//文件读入  
        }
        fpout = fopen(outname,"a");//打开输出文件
        DFS(0); //填入数字 
        if (n>0)//盘数非0时,打印到输出文件 
		   {fprintf(fpout,"\n");} 
		   fclose(fpout);//关闭输出文件
    }
    fclose(fpin);//关闭输入文件
    return 0;
}

示例测试:

3宫格

4宫格

5宫格

6宫格

7宫格

8宫格

9宫格

性能测试


感想:

这次的作业有很多新知识,包括文件输入和输出,vs2017的编译和性能分析的使用,异常处理等等以及gethub的使用。发现自己有很多不懂,需要好好沉淀下这次的新知识,努力提升自己。

posted @ 2019-09-25 21:50  灬R灬  阅读(343)  评论(3编辑  收藏  举报