2019春第十二周作业


这个作业属于哪个课程 C语言程序设计
这个作业的要求在哪里 https://edu.cnblogs.com/campus/zswxy/software-engineering-class2-2018/homework/3234
我在这个课程的目标是 二级指针的概念,了解指针与函数的关系,掌握单向链表的概念和操作
这个作业在哪个具体方面帮助我实现目标 通过理解书上的概念和例题
参考文献 C语言程序设计

一.基础题

6-1 计算最长的字符串长度 (15 分)

本题要求实现一个函数,用于计算有n个元素的指针数组s中最长的字符串的长度。
函数接口定义:

int max_len( char *s[], int n );

其中n个字符串存储在s[]中,函数max_len应返回其中最长字符串的长度。
裁判测试程序样例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXN 10
#define MAXS 20

int max_len( char *s[], int n );

int main()
{
    int i, n;
    char *string[MAXN] = {NULL};

    scanf("%d", &n);
    for(i = 0; i < n; i++) {
        string[i] = (char *)malloc(sizeof(char)*MAXS);
        scanf("%s", string[i]);
    }
    printf("%d\n", max_len(string, n));

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

4
blue
yellow
red
green

输出样例:

6

1.实验代码

int max_len( char *s[], int n )
{
	char *op;
	op=*(s+0);
	for(int i=1;i<n;i++){
		if(strlen(op)<strlen(*(s+i))){
			op=*(s+i);
		}
	}
	return strlen(op);
}

2.设计思路

3.本题调试过称中遇到的问题及解决办法

本题一次性通过,没有遇到问题

4.运行截图

6-2 统计专业人数 (15 分)

本题要求实现一个函数,统计学生学号链表中专业为计算机的学生人数。链表结点定义如下:

struct ListNode {
    char code[8];
    struct ListNode *next;
};

这里学生的学号共7位数字,其中第2、3位是专业编号。计算机专业的编号为02。
函数接口定义:

int countcs( struct ListNode *head );

其中head是用户传入的学生学号链表的头指针;函数countcs统计并返回head链表中专业为计算机的学生人数。
裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct ListNode {
    char code[8];
    struct ListNode *next;
};

struct ListNode *createlist(); /*裁判实现,细节不表*/
int countcs( struct ListNode *head );

int main()
{
    struct ListNode  *head;

    head = createlist();
    printf("%d\n", countcs(head));
	
    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

1021202
2022310
8102134
1030912
3110203
4021205
#

输出样例:

3

1.实验代码

int countcs( struct ListNode *head )
{
	if(head==NULL){
		return 0;
	}
	int num=0;
	struct ListNode *str;
	str=head;
	while(str!=NULL){
		if(str->code[1]=='0'&&str->code[2]=='2'){
			num++;
		}
		str=str->next;
	}
	return num;
} 

2.设计思路

3.本题调试过称中遇到的问题及解决办法


问题:1.没有考虑没有传入学生学号的情况;2.忘记打str=str->next;
解决办法:考虑没有传入学生学号的情况;加上代码str=str->next;

4.运行截图

6-3 删除单链表偶数节点 (20 分)

本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中偶数值的结点删除。链表结点定义如下:

struct ListNode {
    int data;
    struct ListNode *next;
};

函数接口定义:

struct ListNode *createlist();
struct ListNode *deleteeven( struct ListNode *head );

函数createlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。
函数deleteeven将单链表head中偶数值的结点删除,返回结果链表的头指针。
裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *createlist();
struct ListNode *deleteeven( struct ListNode *head );
void printlist( struct ListNode *head )
{
     struct ListNode *p = head;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode *head;

    head = createlist();
    head = deleteeven(head);
    printlist(head);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

1 2 2 3 4 5 6 7 -1

输出样例:

1 3 5 7 

1.实验代码

/*函数createlist从标准输入读入一系列正整数,
按照读入顺序建立单链表。当读到-1时表示输入结束,函数应返回指向单链表头结点的指针。*/
struct ListNode *createlist()
{
	struct ListNode *str,*p,*tail;
	int n;
	int size=sizeof(struct ListNode);  /*计算结构函数struct ListNode所占的字节数*/
	
	str=tail=NULL;
	scanf("%d",&n);
	while(n!=-1){
		p=(struct ListNode*)malloc(size);
		p->data=n;
		p->next=NULL;  /*由于新增加的结点总是加在链表的末尾,所以该新增结点的next域应置成NULL*/
		if(str==NULL) /*建立链表的第一个结点时,整个链表时空的,这时候应直接赋值给head,
		                   而不是tail->next,因为此时tail还是空的,还没有结点可指向*/
			str=p;
		else
			tail->next=p;
		tail=p;	
		scanf("%d",&n); 
	}
	return str;
}

/*函数deleteeven将单链表head中偶数值的结点删除,返回结果链表的头指针。*/
struct ListNode *deleteeven( struct ListNode *head )
{
	struct ListNode *ptr1,*ptr2;
	/*要被删除的结点为表头结点*/
	while(head!=NULL&&((head->data)%2==0)){
		ptr2=head;
		head=head->next;
		free(ptr2);
	}
	/*链表空*/
	if(head==NULL)
		return NULL;
	/*要被删除的结点为非表头结点*/
	ptr1=head;
	ptr2=head->next;
	while(ptr2!=NULL){  /*从表头的下一个结点搜索所有符合删除要求的结点*/ 
		if((ptr2->data)%2==0){
			ptr1->next=ptr2->next;
			free(ptr2);
		}
		else
			ptr1=ptr2; /*ptr1后移一个结点*/
			
		ptr2=ptr1->next; /*ptr2指向ptr1的后一个结点*/ 
	}
	return head;	
}

2.设计思路

3.本题调试过称中遇到的问题及解决办法

这题照着书上的例题做的,一次性通过,没有遇到问题

4.运行截图

二.挑战题

7-1 ***八皇后问题 (20 分)

在国际象棋中,皇后是最厉害的棋子,可以横走、直走,还可以斜走。棋手马克斯·贝瑟尔 1848 年提出著名的八皇后问题:即在 8 × 8 的棋盘上摆放八个皇后,使其不能互相攻击 —— 即任意两个皇后都不能处于同一行、同一列或同一条斜线上。
现在我们把棋盘扩展到 n × n 的棋盘上摆放 n 个皇后,请问该怎么摆?请编写程序,输入正整数 n,输出全部摆法(棋盘格子空白处显示句点“.”,皇后处显示字母“Q”,每两格之间空一格)。
输入格式

正整数 n (0 < n ≤ 12)

输出格式

若问题有解,则输出全部摆法(两种摆法之间空一行),否则输出 None。

要求:试探的顺序逐行从左往右的顺序进行,请参看输出样例2。
输入样例1

3

输出样例1

None

输入样例2

6

输出样例2

. Q . . . .
. . . Q . .
. . . . . Q
Q . . . . .
. . Q . . .
. . . . Q .

. . Q . . .
. . . . . Q
. Q . . . .
. . . . Q .
Q . . . . .
. . . Q . .

. . . Q . .
Q . . . . .
. . . . Q .
. Q . . . .
. . . . . Q
. . Q . . .

. . . . Q .
. . Q . . .
Q . . . . .
. . . . . Q
. . . Q . .
. Q . . . .

1.实验代码

#include<stdio.h>
#include<math.h>
int judge(int x,int y);
void traverse(int x);
void show();

int n,f=0,sun=0;
int str[13]={0};

/*主函数——输入*/
int main()
{
	scanf("%d",&n);
	traverse(1);  //从第一行开始,逐行放一个皇后 
	if(sun==0){   //若问题无解则输出None; 
		printf("None");
	}	
 } 
 
 /*放皇后*/
void traverse(int x)
{
 	if(x<=n)  //一直放到棋盘的最后一行 
 	{
 		for(int i=1;i<=n;i++){
 			int z=judge(x,i);  //判断第x行的第i列的位置是否可以放皇后 
 			if(z==0){  //若返回值为0,即该位置可以放皇后,则将第x行放的皇后的位置(即第i列)储存在str[x]里; 
 				str[x]=i;
 				traverse(x+1);  //若上一行的皇后已经放好后,则就可以继续放下一行的皇后。 
			 }
		 }
	 }
	 else  //若x>n,则说明最后一行的皇后已经放完了,即已经放完了一盘棋了,可以将这一盘棋输出了; 
	 {
	 	show();
	 	sun=1;  //若最少输出了一盘棋,则说明问题有解; 
	 }
}
 
 /*判断该位置是否可以放皇后*/ 
 int judge(int x,int y)
 {
 	for(int i=1;i<x;i++)  //判断第x行的上面几行的皇后是否和第x行的第y列的皇后位于同列或同斜线。 
	 {
	 	if(str[i]==y||(abs(i-x)==abs(str[i]-y)))  //若两个皇后处于同斜线,则两皇后位置的行差和列差的绝对值相等 
		 {
	 		return -1;  //若处于同列或同行,即该位置不可以放皇后,则返回-1 
		 }
	 }
	 return 0;  //与上面几行都判断完后,都没有发现有皇后和第x行的第y列的皇后位于同列或同斜线,即该位置可以放皇后,则返回0; 
 }
 
 /*输出棋盘摆法*/
 void show()
 {
 	if(f==1){   //空一行后再输出棋盘,而不是输出棋盘后再空一行,防止输出最后一种解法的棋盘后,还要多输出一条空行; 
 		printf("\n");
	 }
 	for(int i=1;i<=n;i++)
 	{
 		for(int j=1;j<=n;j++)
 		{
 			if(str[i]==j){
 				printf("Q");
			 }
			 else{
			 	printf(".");
			 }
			 if(j!=n){  //若是最后一列,则不需要输出空格; 
			 	printf(" ");
			 } 
		 }
		 printf("\n");
		 f=1;  //将f赋值1,若有多种解,则输出第一种解后,再在后面输出的棋盘前面空一行; 
	 }
 }

2.设计思路

3.本题调试过称中遇到的问题及解决办法

这题我是看了计科四班助教的视频和李代传的代码,,搞明白四班助教的代码,然后自己做出来,一次性通过。

4.运行截图

三.学习感悟

这周学习的三个课程都比较难以理解,特别是单向链表的概念和操作(建立、增加、删除、修改、遍历),这一部分我也看了很久才有一点概念,基础题的第三题和书上的例题差不多,只要书上的例题理解了,那么这个题目就很容易做出来,其他两个题目都还好,主要是理解书上的概念;这周的挑战题我和上周一样,都没有思路,八皇后我还是看了别人的代码和视频,搞明白后,我才做出来的;找最短迷宫的路径这题,网友的我也看不明白,感觉好复杂,而且也没有时间了,就没做了。

四.预习作业

1.所在小组想要开发的项目的名称和目标;

还没考虑好

2.项目主体功能的描述;

3.现阶段已做的准备工作;

4.小组成员名单和进度安排。

小组成员:刘伟,任森柱,李健

五.结对编程感想

过程:讨论了基础题的最后一题;一起看书、看例题。
感想:理解了单向链表的概念和操作(建立、增加、删除、修改、遍历),并且将第三题做出来了。

六.学习进度条


周/日期 这周所花的时间 代码行 学到的知识点简介 目前比较迷惑的问题
2/25-3/3 6h 39 一维数组的定义和引用及初始化 字符数组和整型数组的区别
3/4-3/10 12h 47 指针的定义及运用;文件的读取、写入, 处理和开关;文件的打开方. 文件的分类,什么是文本文件, 什么是二进制文件;字符数组的读取和写入
3/11-3/17 6h 57 二维数组的定义及应用 二维数组的行和列的嵌套循环输入和输出
3/18-3/24 12h 98 选择排序法、冒泡排序法和二分查找法 不清楚选择排序法和冒泡排序法的区别
3/25-3/31 20h 88 字符数组和字符串的区别,字符串的输入输出方式和格式,二维数组更高级的运用。 不清楚指针在程序中的作用
4/1-4/7 12h 70 变量、内存单元和地址之间的关系;指针变量的定义及初始化,指针变量的基本运算,指针、数组和地址间的关系 二分法查找法不太明白
4/8-4/14 11h 99 掌握数组名作为函数参数的用法,理解指针、数组和地址之间的关系,理解指针和数组可以实现相同的操作 好像忘记了,可能没有
4/15-4/21 12h 132 掌握常用字符串函数以及使用指针操作字符串的方法,掌握动态内存分配 各个动态内存分配函数的区别还是不太清楚
4/22-4/28 12h 133 合理定义结构,使用结构变量与结构数组编程,掌握结构指针的操作,并应用于函数传递 解递归式的三种方法不太理解
4/29-5/4 7h 0 结构数组及结构指针;如何提高自己与他人的竞争力?如何有效的记忆和学习?如何提问? 各个动态内存分配函数的使用还是不太清楚
5/5-5/11 36h 26 能够使用递归函数进行编程;掌握宏的基本用法;掌握编译预处理的概念 如何熟练使用递归函数
5/12-5/18 12h 229 二级指针的概念,了解指针与函数的关系,掌握指针作为函数返回值,掌握单向链表的概念和操作 如何找出迷宫的最短路径

七.表格和折线图


时间 代码行数 博客字数
第一周 39 1754
第二周 47 2087
第三周 57 1993
第四周 98 2145
第五周 88 2472
第六周 70 2514
第七周 99 3127
第八周 132 3313
第九周 133 2897
第十一周 26 3026
第十二周 229 3092

posted @ 2019-05-17 22:42  新设备  阅读(203)  评论(0编辑  收藏  举报