程序设计综合实训报告整理

姓名:杨xx

学号:17272xxx/

运行环境:VS2017/DevC++

 

  • 模块化程序与递归函数设计

prob1:整数的划分

思路

分析示例可得如下划分规律

1.第一个划分数为n-1~1

2.每一次划分后的余下部分不得大于前一个划分数。

故设置一个全局数组用于动态存储每一次划分的结果

然后在一个for循环中先降序划分出来第一个数x,再将余下部分n-x进行再划分。

因为要满足2规律方可使划分结果不重复,所以对划分数的划分需从划分数~1,当划分后余下的部分<=0时终止划分,输出本次划分结果。

代码实现:

#include<iostream>
#include<conio.h>
using namespace std;

int num[100];								//存储划分的数
	
void print(int k)							//输出一次拆分的结果,k为拆分的个数
{
	cout << num[0] << "=" << num[1];
	for (int i = 2; i <= k; i++)
		cout << "+" << num[i];
	cout << endl;
}
void split(int k, int n)					//n为待拆分数,即上一步拆分后最原始数剩余的部分
{
	if (n <= 0)								//n<0说明已拆分完全
		print(k);
	else
		for (int i = n; i >= 1; --i)		//
		{
			if (i <= num[k])				//确保拆分出来的数小于前一位拆分出来的数
			{
				num[k+1] = i;					//将拆分出来的数存储进num[k+1]里
				split(k + 1, n - i);		//余下部分继续拆分,直到满足终止条件为止
			}
		}

}
int main()
{
	cin >> num[0];
	for (int i = num[0] - 1; i >= 1; i--)	//先拆分出来第一位数
	{
		num[1] = i;
		split(1, num[0] - i);
	}

	_getch();
	return 0;
}

运行截图

 

prob2:递归实现走迷宫

代码实现:

#include<iostream>
using namespace std;

//迷宫的布局放入到一个二维的数组中
//                        0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
int mizu[10][10] = {1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,  //0
                          1 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1,  //1
                          1 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1,  //2
                          1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1,  //3
                          1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1,  //4
                          1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1,  //5
                          1 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 1,  //6
                          1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 1,  //7
                          1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1,  //8
                          1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1   //9
} ;

int flag[10][10];//定义操作数组

void putout(int a[10][10])//输出数组,可输出不同数组
{
	int i,j;
    for(i=0;i<=9;i++)
        for(j=0;j<=9;j++)
    	{
        if(a[i][j]==2)
            cout << "*";//2则输出路径*
        if(a[i][j]==1)
            cout << "x";//1则输出x
        if(a[i][j]==0)
            cout << " ";//0则输出 空格
    	if(j==9)
			cout << "\n";
	}
	cout << endl << endl;
}
void nextstep(int x,int y)
{
	if(x==8&&y==8)
    	putout(flag);
    flag[x][y]=2;
	if(flag[x+1][y]==0)//right is passable
    	nextstep(x+1,y);
	if(flag[x-1][y]==0)//left is passable
    	nextstep(x-1,y);
	if(flag[x][y-1]==0)//down is passable
    	nextstep(x,y-1);
	if(flag[x][y+1]==0)//up is passable
    	nextstep(x,y+1);
	flag[x][y]=0;

}//调用自身完成递归
int main()
{    int i,j;
    for(i=0;i<=9;i++)
        for(j=0;j<=9;j++)
            flag[i][j]=mizu[i][j];
    int x=1,y=1;
    cout << "迷宫构造" << endl;
    putout(mizu);
	cout << "5秒后将打印所有能走的方法:" << endl;
    
    nextstep(x,y);
    
    return 0;
}

 

运行截图

 

结构/链表与堆栈

prob1:猴子选大王

思路:

分析可知,每个猴子节点应该带有三个域,一个为猴子编号;一个为猴子的定数,用于确定下一个删除猴子节点的位置;一个为指向下一个猴子的指针,用于确定猴子之间的关系。

步骤:

1.动态创建一个猴子单向循环链

2.函数DeleteNext(p):删除猴子节点p;当选中猴子p时,只需将p->next指向p->next->next,可设置一个新的节点指针指向待删除的节点。若只是p->next=p-next->next,虽然成功指向,但被删除的猴子所占并内存没得到释放,会造成内存空间浪费。

3. 挑选函数

代码实现:

#include<iostream>
#include<stdlib.h>
using namespace std;

typedef struct node{//这个结构类型包括三个域
	int number;//猴子的编号
	int mydata;//猴子的定数
	struct node*next;//指向下一个猴子的指针
}linklist;

linklist *Creatcircle(int n) //创建一个猴子的单向循环链
{
	linklist *head,*p,*s;
	p=head = (linklist*)malloc(sizeof(linklist));//首节点创建
	p -> number = 1; //为第一个猴子编号
	cin >> p->mydata;//定数,确定下一只出局的猴子
	p->next = NULL;
	for(int i = 2;i <= n;i++)//	创建链表
	{
		s=(linklist*)malloc(sizeof(linklist));//创建一个新的节点
		s->number = i;//为新节点的编号赋值
		cin >> s->mydata;//定数(报数),确定下一只出局的猴子
		p->next = s;//将前节点尾指向新节点(添加猴子进猴子圈)
		p=s;//前节点指针标志指向新节点,成为新的尾节点
	}
	p->next = head;//尾节点的指针指向头节点,将表链接成圈
	return p;
}

linklist *DeleteNext(linklist *p)//删除单循环链表的p所指的下一个节点
{
	linklist *b = p->next; //b节点指向p节点的节点指针指向的节点
	p->next = b->next;//
	free(b);//释放b节点,即p->next节点
	return p;
}

int KingOfMonkey(int n,linklist *head)  //挑选大王
{
	linklist *p = head;//初始p指针指向头节点
	int i,j,steps = p->mydata;//从头节点的定数开始进行遍历删除
	for(j = 1;j < n;j++)//删除操作共需n-1步
	{
		for(i = 1;i < steps;i++) //按照定数搜索待删除的节点
		p = p->next;   //累加步数,直到达到定数
		steps = p->next->mydata;  //存储当前待删猴子的定数(既下一待删猴子的位置)
		cout << p->next->number << endl; //输出当前待删猴子的编号
		DeleteNext(p);//将当前节点从表中删除
	}
	return p->number;//返货最终胜利的猴子,既猴王
}

int main()
{
	linklist *head;
	int n;
	cout << "请输入猴子的总数和每只猴子的定数(必须是正整数):";
	cin >> n;
	head = Creatcircle(n);
	cout << endl << "the king if monkey[" << KingOfMonkey(n,head) << "]." << endl;
	return 0;
}

运行截图

 

prob2:链表表示一元n次多项式,实现多项式的加/减以及乘法运算

思路:

1.分析一元n次多项式的结构,每个项节点应包含三个域,一个次数域,一个系数域,一个指针域;

2.分析一元n次多项式的加/减/乘运算可知,加法与减法较易实现,次数相同的相加/减即可,但应注意格式输出时对正负号以及对系数为0时的控制;而乘法较复杂,结果链表需伸长至多2n个节点。

3.由于运算是从低次向高次遍历计算,而规范输出是从高次向低次遍历输出,所以需构建双向链表,既指针域有两个next和pre。

步骤

  1. 输入n
  2. 动态创建两个长度为n的链表
  3. 加法运算,需要一个长度为n的链表存储结果
  4. 减法运算,需要一个长度为n的链表存储结果
  5. 乘法运算,需要一个长度为2n的链表存储结果
  6. 将加/减/乘的结果输出

 

代码实现

#include<iostream>
using namespace std;

typedef struct linklist{
	int tim;				//指数 
	int coe;				//系数 
	struct linklist *next;
	struct linklist *pre;
}linklist;


/*构建多项式,并返回多项式的头指针*/
linklist *CreatePOOI(int n)
{
	linklist *head,*end,*New;
	end = head =  (linklist*)malloc(sizeof(linklist));
	end->tim = n;
	cin >> end->coe;			//输入系数
	end->next =NULL;
	end->pre = NULL;
	
	for(int i = n-1;i >= 0;i--)
	{
		New=(linklist*)malloc(sizeof(linklist));
		New->tim = i;			//由高次向低次依次为多项式的次数赋值
		cin >> New->coe;		//由高次向低次依次为多项式的系数赋值
		
		end->next = New;		//将前一节点尾指向新节点
		New->next = NULL;
		New->pre = end;			//将新节点的前序指针指向前一节点 
		end = New;				//新尾节点标志设置为新节点 
	}
	return head;
}

/*构建系数均为零的多项式,并返回多项式的头指针*/
linklist *CreateEmptyPOOI(int n)
{
	linklist *head,*end,*New;
	end = head =  (linklist*)malloc(sizeof(linklist));
	end->tim = n;
	end->coe = 0;			//输入系数
	end->next =NULL;
	end->pre = NULL;
	
	for(int i = n-1;i >= 0;i--)
	{
		New=(linklist*)malloc(sizeof(linklist));
		New->tim = i;			//由高次向低次依次为多项式的次数赋值
		New->coe = 0;		//由高次向低次依次为多项式的系数赋值
		
		end->next = New;		//将前一节点尾指向新节点
		New->next = NULL;
		New->pre = end;			//将新节点的前序指针指向前一节点 
		end = New;				//新尾节点标志设置为新节点 
	}
	return head;
}

/*规范输出多项式*/
void ShowPOOI(linklist *p)
{
	if(p->coe == 0)
	;
	else
		cout << p->coe << "*n^" << p->tim;
	p = p->next;
	while(p->next != NULL)
	{
		if(p->coe < 0)
			cout << p->coe << "*n^" << p->tim;
		else if(p->coe > 0)
			cout << "+" << p->coe << "*n^" << p->tim;
		else
		;
		p = p->next;
	}
	if(p->coe < 0)
		cout << p->coe <<endl;
	else if(p->coe > 0)
		cout << "+" << p->coe <<endl;
	else
		;
	cout << endl;
}

/*多项式求和,返回结果多项式的头指针*/
linklist *SumPOOI(linklist *ls_1,linklist *ls_2,int n)//n为最高次数 
{
	linklist *SUM,*Tail;
	Tail = SUM = CreateEmptyPOOI(n);
	while(SUM->next != NULL)
		SUM = SUM->next;
	while(ls_1->next != NULL)
		ls_1 = ls_1->next;
	while(ls_2->next != NULL)
		ls_2 = ls_2->next;
	while(ls_1->pre != NULL)
	{
		SUM->coe=ls_1->coe + ls_2->coe;
		SUM = SUM->pre;
		ls_1 = ls_1->pre;
		ls_2 = ls_2->pre;
	}
	//对正数第1位的运算 
	SUM->coe=ls_1->coe + ls_2->coe;
	
	return Tail;
}

/*多项式求差,返回结果多项式的头指针*/
linklist *DiffPOOI(linklist *ls_1,linklist *ls_2,int n)//n为最高次数 
{
	linklist *DIFF,*Tail;
	Tail = DIFF = CreateEmptyPOOI(n);
	while(DIFF->next != NULL)
		DIFF = DIFF->next;
	while(ls_1->next != NULL)
		ls_1 = ls_1->next;
	while(ls_2->next != NULL)
		ls_2 = ls_2->next;
	while(ls_1->pre != NULL)
	{
		DIFF->coe=ls_1->coe - ls_2->coe;
		DIFF = DIFF->pre;
		ls_1 = ls_1->pre;
		ls_2 = ls_2->pre;
	}
	//对正数第1位的运算 
	DIFF->coe=ls_1->coe - ls_2->coe;
	
	return Tail;
}

/*多项式求积,返回结果多项式的头指针*/
linklist *ProdPOOI(linklist *ls_1,linklist *ls_2,int n)//n为最高次数 
{
	linklist *PROD,*Tail;
	Tail = PROD = CreateEmptyPOOI(2*n);
	while(PROD->next != NULL)//3个while作用:找到常数项,从常数项开始按指数升序计算 
		PROD = PROD->next;
	while(ls_1->next != NULL)
		ls_1 = ls_1->next;
	while(ls_2->next != NULL)
		ls_2 = ls_2->next;
	
	//计算PROD的指数n对应的系数时,当ls_1的指数项为i=0~n,则j=n-i~n,Sum=i*j累加; 
	linklist *i,*j,*iHead,*jHead;//iHead和jHead始终指向ls_1和ls_2的表尾:常数项; 为i,j提供每次循环的初始条件
	i = iHead =ls_1;
	j = jHead = ls_2;
	
	for(PROD;PROD->pre != NULL;PROD=PROD->pre)
	{
		for(i = iHead;i->pre != NULL;i = i->pre)
		{
			for(j = jHead;j->pre != NULL;j = j->pre)
			{
				if(i->tim + j->tim == PROD->tim)//当ls_1的指数+ls_2的指数等于PROD的指数时
				{
					PROD->coe += (i->coe*j->coe);
				}
			}
			PROD->coe += (i->coe * j->coe);//为什么有这步以及line:164,line:166,因为每次循环后最高次数项都会漏算 
		}
		PROD->coe += (i->coe * j->coe);
	}
	PROD->coe += (ls_1->coe * ls_2->coe);
	//nice nice nice
	return Tail;
}

int main()
{
	int n;
	linklist *ls_1,*ls_2,*ls_sum,*ls_diff,*ls_prod;
	cout << "please input n:";
	cin >> n;
	cout << "构建链表1" << endl;
	ls_1 = CreatePOOI(n);
	cout << "构建链表2" << endl;
	ls_2 = CreatePOOI(n);
	cout << "一元多项式1:"; 
	ShowPOOI(ls_1);
	cout << "一元多项式2:"; 
	ShowPOOI(ls_2);
	
	
	ls_sum = SumPOOI(ls_1,ls_2,n);
	cout << "多项式1和2的和:"; 
	ShowPOOI(ls_sum);
	
	ls_diff = DiffPOOI(ls_1,ls_2,n);
	cout << "多项式1和2的差:"; 
	ShowPOOI(ls_diff);
	
	ls_prod = ProdPOOI(ls_1,ls_2,n);
	cout << "多项式1和2的积:"; 
	ShowPOOI(ls_prod);
}

运行截图

  • 图形程序设计基础

prob1:画房子

关键在于计算坐标,最简洁的方法是一个line函数搞定.

代码实现:

#include "graphics.h"

int main(void)
{
	initgraph(638,512);   // 初始化绘图环境

	line(175, 211, 175, 391);
	line(175, 211, 463, 211);
	line(463, 211, 463, 391);
	line(175, 391, 463, 391);
	line(175, 301, 463, 301);
	line(247, 199, 247, 391);
	line(319, 199, 319, 391);
	line(391, 211, 391, 391);
	line(211, 121, 175, 211);
	line(211, 121, 247, 211);
	line(427, 121, 391, 211);
	line(427, 121, 463, 211);
	line(259, 199, 247, 199);
	line(259, 199, 259, 211);
	line(271, 211, 271, 199);
	line(271, 199, 283, 199);
	line(283, 199, 283, 211);
	line(295, 211, 295, 199);
	line(295, 199, 307, 199);
	line(307, 199, 307, 211);
	line(331, 199, 319, 199);
	line(331, 199, 331, 211);
	line(343, 211, 343, 199);
	line(343, 199, 355, 199);
	line(355, 199, 355, 211);
	line(367, 211, 367, 199);
	line(367, 199, 379, 199);
	line(379, 199, 379, 211);

	ege::getch();
	closegraph();

	return 0;
}

运行截图

 prob2:画多边形

思路

分析多边形,可看出是由以下图形绕一点旋转20°连续旋转18次得到,且线段长度不变.

  1. 可设置一个循环,在循环里设置一个初始为0°,每一次增加20°的角度变量(因为要用到sin和cos函数所以需转换为弧度制),再对每一次旋转后进行画线操作。
  2. 分析每一次的画线操作,可得到如下相同的画线规律

沿当前角度(第1步骤中的角度)画线->逆时针旋转60°->画线->逆时针旋转-120°->画线->逆时针旋转-60°->画线->逆时针旋转120°->画线

此步骤在draw函数中实现

  1. 旋转角度函数turn
  2. 移动画线的起始坐标函数move
  3. 沿特定角度画线函数forward

实现代码<

CSU 大一上 C语言实验报告 (1)教材第2章编程题第2题:编计算球体体积的程序。 说明:本题声明适当变量,用户键入数据,运算并输出结果,较简单。 (2)教材第2章编程题第8题:编程序计算第一、第二、第三月还贷后剩余贷款金额。 说明:本题要求用户输入总额、利率、每月还贷净额,输出每月剩余,对输入输出、类型定义考查。 (3)教材第3章编程题第2题:编程序实现对用户输入的产品信息进行格式化。 说明:本题考查格式化输入输出、转义字符的运用。 (4)教材第4章编程题第4题:编程序实现将输入的整数按八进制输出。 说明:本题重在考查简单的运算符和表达式运用。 (5)用户输入一个三位数,输出各位数字之和。 说明:本题重在考查如何从一个整数中取出每一个数字。 (6)教材第5章编程题第5题:编程序计算用户输入所得额的税金。 说明:本题考查简单的择结构。 (7)教材第5章编程题第11题:编程序实现将用户输入的两位数转化为英文。 说明:本题考查switch语句的应用。 (8)教材第6章编程题第8题:编程序显示单月日历,用户指定这个月的天数和该月起始日是星期几。 说明:本题考查循环结构和择结构的综合应用,判断是否一个星期最后一天,换行符。 (9)教材第6章编程题第11题:编程序实现利用无穷级数法估计e的值。 说明:本题考查根据公式设计循环结构并实现。 (10)因子之和等于其本身的数称为完数,如28的因子为1、2、4、7、14,而28=1+2+4+7+14,因此28为完数。编程序找出2~5000中的完数。 说明:本题利用变量i在2~5000中变化,判断其是否是完数。 (11)教材第7章编程题第12题:编程计算从左至右求值的表达式的值。 说明:本题考查对运算符和操作数的判断。 (12)教材第7章编程题第14题:编程序用牛顿计算法计算浮点数平方根。 说明:本题考查对循环结构的掌握,对表达式的合理运用,对基本类型的理解。 (13)教材第8章编程题第14题:编程序颠倒句子中单词的顺序。 说明:本题考查对字符数组的处理,对一些循环择结构的理解。 (14)教材第8章编程题第15题:编程序实现凯撒密码加密。 说明:本题考查对字符数组的掌握,对字符处理的理解。 (15)编程序实现将用户输入的数字字符串转化为整数输出。 说明:本题考察对字符、整数关系的掌握与理解,对循环结构的熟练运用。 (16)教材第9章编程题第1题:编择排序的函数,并递归调用。 说明:本题利用函数简化程序、使得结构更清晰、熟练掌握。 (17)教材第9章编程题第7题:编计算xn的函数。 说明:本题考查函数定义、调用,并初步考察递归运用。 (18)教材第10章编程题第6题:编程序实现逆波兰运算。 说明:本题考查对程序每部分的理解、掌握,外部、内部变量,主函数,小函数的编与应用。初步了解栈的一些实现函数。 (19)编程序找出2~5000中满足条件的数x:x是素数且x的每位数字是素数、每位数字之和是素数,如23、223、2333等。 说明:本题考查函数方法与循环择结构的综合运用。 (20)教材第11章编程题第3题:用指针变量编简化一个分数的函数。 说明:本题用来解决函数无法传回传递的实际参数,指针变量。 (21)教材第12章编程题第2题:编函数读入用户输入的一条消息,检测是否是回文,分别用数组、指针来解决。 说明:本题可以体会到数组与指针的特点,利用指针的便利。 (22)利用指针编程序,实现从键盘键入字符串,将此字符串从m个字符开始的n个字符复制成另一个字符串。 说明:本题用指针指向字符串,进行跟踪和复制操作。 (23)教材第13章编程题第5题:编程序实现对输入命令行参数求和。 说明:本题加深对命令行参数的理解、考查知识的综合应用。 (24)教材第16章编程题第5题:用结构变量解决搜索离用户输入时间最近的航班信息,并输出。 说明:本题考查结构与数组的结合运用,有助于理解结构。首先,定义一个存储起飞、到达时间的结构,再定义一个该类型的数组,循环搜索即可。 (25)教材第17章编程题第5题:用指针数组存储键入的字符串,对数组排序。 说明:本题应用动态分配内存、数组排序,考查综合能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值