C++实验二 控制结构和函数

1 实验目的
(1)灵活掌握控制结构及其逻辑特点,学会逐步求精的算法设计。
(2)学习如何把逻辑结构相同的部分抽象为函数,以提高代码的可重用性,达到提高程序的可维护性的目的。
(3)学习使用数组作为函数参数的方法。
2 实验内容
2.1 打印温度柱状图
(1)问题描述
下图是某城市15天的气温变化曲线。其中标注为A的地方称为峰点,标记为B的地方称为谷点,而标记为C的地方称为崮。要求编写1个函数输入15天的气温,然后通过3个函数分别实现下述功能:
(1)打印每天温度的柱状图(仅考虑温度为正值的情况)。
(2)打印所有峰点的位置(该月的第几天)及峰值。如果没有,则打印没有峰值。
(3)打印最长的崮的长度。只使用一重循环即可求出。
在这里插入图片描述
(2)问题要求
请实现以下函数声明,要求能得到如下图所示的运行结果。

在这里插入图片描述
在这里插入图片描述
源代码如下:

#include<iostream>

#include<iomanip>
#include<vector>
using namespace std;

void inputTemps(int temp[], int n);
void displayTemps(int temp[], int n);
void displayPeaks(int temp[], int n);
void displayFlats(int temp[], int n);

int main() {
	int temp[15];
	int n = 15;
	inputTemps(temp, n);
	displayTemps(temp, n);
	displayPeaks(temp, n);
	displayFlats(temp, n);
}


void inputTemps(int temp[], int n) {
	int i;
	cout << "Input " << n << " temperatures:" << endl;
	for (i = 0; i < n; i++)
		cin >> temp[i];
	cout << endl;
}


void displayTemps(int temp[], int n) {
	int i, j;
	cout << "显示柱状图如下:" << endl;
	for (i = 0; i < n; i++) {
		cout << setw(2) << i + 1 << "\t";
		for (j = 0; j < temp[i]; j++)
			cout << "*";
		cout << endl;
	}
}


void displayPeaks(int temp[], int n) {
	int i, p = 0;
	cout << endl << "显示峰值如下:" << endl;
	for (i = 1; i < n - 1; i++) {
		if (temp[i] > temp[i - 1] && temp[i] > temp[i + 1]) {
			cout << "Max at day " << i + 1 << " is " << temp[i] << endl;
			p = 1;
		}
	}
	if (p == 0)
		cout << "No max!" << endl;
}


void displayFlats(int temp[], int n) {
	int i, j = 1, k = 1;
	for (i = 1; i < n; i++) {

		if (temp[i] == temp[i - 1])
			j++;
		else {
			if (j > k)
				k = j;
			j = 1;
		}
	}
	if (j > k)
		k = j;
	cout << endl << "The length of longest flat is " << k << endl;

}

2.2 处理零下温度
(1)要求柱状图能够处理多个零下温度的情况,以如下形式打印。
在这里插入图片描述
(2)求出现次数最多的温度,及其出现次数。
例如:12 13 12 12 14 13 13 12 13 13 中,出现次数最多的是13度,出现了5次。
源代码如下:

#include<iostream>

#include<iomanip>
#include<vector>
using namespace std;

void inputTemps(int temp[], int n);
void displayTemps(int temp[], int n);
void findMax(int temp[], int n);



int main() {
	int temp[15];
	inputTemps(temp, 15);
	displayTemps(temp, 15);
	findMax(temp, 15);
}


void inputTemps(int temp[], int n) {
	int i;
	cout << "Input " << n << " temperatures:" << endl;
	for (i = 0; i < n; i++)
		cin >> temp[i];
	cout << endl;
}


void displayTemps(int temp[], int n) {
	int i, j;
	cout << endl << "显示柱状图如下:" << endl;
	for (i = 0; i < n; i++) {
		cout << setw(2) << temp[i];
		if (temp[i] > 0||temp[i]==0) {
			for (j = 0; j < 10; j++)
				cout << " ";
			cout << "|";
			for (j = 0; j < temp[i]; j++)
				cout << "*";
			cout << endl;
		}
		else {
			for (j = 0; j < 10 + temp[i];j++)
				cout << " ";
			for (j = 0; j < -1 * temp[i]; j++)
				cout << "*";
			cout << "|" << endl;
		}
	}
}

void findMax(int temp[], int n) {
	int a[15];
	int i, j, max;
	for (i = 0; i < n; i++) {
		a[i] = 1;
		for (j = i; j < n; j++) {
			if (temp[i] == temp[j])
				a[i]++;
		}
	}
	max = a[0];
	j = 0;
	for (i = 1; i < n; i++) {
		if (a[i] > max) {
			max = a[i];
			j = i;
		}
	}
	cout <<endl<< "出现最多的是" << temp[j] << "出现了" << max-1<<"次";
}

2.3 滑块游戏
(1)问题描述
滑块游戏的棋盘结构及某一种滑块的初始排列结构如图所示。

滑块游戏的初始格局
其中,B表示黑色滑块,W表示白色滑块,E表示空格。我们称滑块的排列结构称为格局。根据单色滑块的个数,将游戏分别称为3滑块或4滑块游戏等。所以,上图就是3滑块游戏的初始格局。我们可以用字符串来代表格局,代表上图中初始格局的字符串为BBBWWWE。
游戏的规定走法是:
(1)任意一个滑块可以移入相邻的空格;
(2)任意一个滑块可相隔1个或2个其他的滑块跳入空格。
游戏要达到的目标是使所有白滑块都处在黑滑块的左边(左边有无空格均可),我们称为目标格局。很显然,3滑块游戏的目标格局共有7种。
随着滑块的移动,我们会得到一些中间格局,例如:

滑块游戏的某个中间格局
对于某个格局,通过一次移动滑块而得到的格局,称为其后继格局。我们需要找到某个中间格局的所有后继格局,即每种可能的走法所能得到的格局。
(2)输入
输入的第一行是一个整数N,表示共有N个格局。后续紧跟N行,每行由两部分构成,第一部分是一个整数n,表示这是一个n滑块游戏,第二部分是2n + 1个字符,表示该游戏的某个格局。
(3)输出
首先判断输入的格局是否是目标格局,如果是,则输出“目标格局”后结束;
如果不是目标格局,则按顺序(将格局看作字符串后,按照字典序排序,即B < E < W)输出该格局的所有后继格局。例如,BBEBWWW格局应该排在BBWBWEW格局的前面,因为在英文字母表中,第一个格局中的第3个字符E排在第二个格局的第3个字符W前面
(4)示例
输入
2
3 BBWBEWW
4 WWWWBBEBB
输出
结果_1
BBEBWWW
BBWBWEW
BBWBWWE
BBWEBWW
BEWBBWW
结果_2
目标格局

源代码如下:

#include<iostream>
#include<cstring>
using namespace std;

void swap(char str[], int i, int j) {
	char ch = str[i];
	str[i] = str[j];
	str[j] = ch;
}

void bubbleSort(char **result, int counter, int length) {
	char *str = new char[length];
	for (int i = counter - 1; i > 0; i--)
		for (int j = 0; j < i - 1; j++)
			if (strcmp(result[j + 1], result[j]) < 0) {
				strcpy(str, result[j]);
				strcpy(result[j], result[j + 1]);
				strcpy(result[j + 1], str);
			}
	delete[] str;
}

bool check(char *sliders, int length) {
	int wMaxIndex = 0, bMinIndex = 0;
	bool notFoundB = true;
	for (int i = 0; i < length; i++) {
		if (sliders[i] == 'W')
			wMaxIndex = i;
		if (notFoundB && (sliders[i] == 'B')) {
			bMinIndex = i;
			notFoundB = true;
		}
	}

	if (wMaxIndex < bMinIndex)
		return true;

	return false;
}

int main() {
	const int MAX_NUM = 6;
	int N;

	cin >> N;

	char **buffer = new char *[N];

	for (int i = 0; i < N; i++) {
		int numSlider;
		cin >> numSlider;
		buffer[i] = new char[2 * numSlider + 1];
		cin >> buffer[i];
	}

	for (int k = 0; k < N; k++) {
		int counter = 0;
		int length = strlen(buffer[k]);
		char *sliders = new char[length]; // 输入字符串
		char *result[MAX_NUM];

		cout << "结果_" << k + 1 << endl;

		strcpy(sliders, buffer[k]);

		if (check(sliders, length)) {
			cout << "目标格局" << endl;
			continue;
		}

		for (int i = 0; i < MAX_NUM; i++) {
			result[i] = new char[length];
			strcpy(result[i], sliders);
		}

		int index = 0;
		for (; index < length; index++) { // 查找空格字符E
			if (sliders[index] == 'E')
				break;
		}

		for (int offset = 1; offset < 4; offset++) {
			if (index + offset < length) {
				swap(result[counter], index, index + offset);
				counter++;
			}
			if (index - offset >= 0) {
				swap(result[counter], index, index - offset);
				counter++;
			}
		}

		bubbleSort(result, counter, length);

		for (int m = 0; m < counter; m++)
			cout << result[m] << endl;

		delete[] sliders;
		for (int t = 0; t < MAX_NUM; t++)
			delete[] result[t];

		counter = 0;
	}

	for (int j = 0; j < N; j++)
		delete[] buffer[j];
	delete[] buffer;

	return 0;
}


  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
问题描述:将马随机放在国际象棋的 8X8 棋盘中的某个方格中,马按走棋规则进行移动。要求每个方格上只进入一次,走遍棋盘上全部 64 个方格。编制递归程序,求出马的行走路线 ,并按求出的行走路线,将数字 1,2,…,64 依次填入 8X8 的方阵输出之。测试数据:由读者指定可自行指定一个马的初始位置。实现提示:每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”悔棋使用。并探讨每次选择位置的“最佳策略”,以减少回溯的次数。 背景介绍: 国际象棋为许多令人着迷的娱乐提供了固定的框架,而这些框架常独立于游戏本身。其中的许多框架都基于骑士奇异的L型移动规则。一个经典的例子是骑士漫游问题。从十八世纪初开始,这个问题就引起了数学家和解密爱好者的注意。简单地说,这个问题要求从棋盘上任一个方格开始按规则移动骑士,使之成功的游历国际象棋棋盘的64个方格,且每个方格都接触且仅接触一次。 可以用一种简便的方法表示问题的一个解,即将数字1,……,64按骑士到达的顺序依次放入棋盘的方格中。 一种非常巧妙的解决骑士漫游地方法由J.C.Warnsdorff于1823年给出。他给出的规则是:骑士总是移向那些具有最少出口数且尚未到达的方格之一。其中出口数是指通向尚未到达方格的出口数量。在进一步的阅读之前,你可以尝试利用Warnsdorff规则手工构造出该问题的一个解。 实习任务: 编写一个程序来获得马踏棋盘即骑士漫游问题的一个解。 您的程序需要达到下面的要求: 棋盘的规模是8*8; 对于任意给定的初始化位置进行试验,得到漫游问题的解; 对每次实验,按照棋盘矩阵的方式,打印每个格被行径的顺序编号。 技术提示: 解决这类问题的关键是考虑数据在计算机中的存储表示。可能最自然的表示方法就是把棋盘存储在一个8*8的维数组board中。以(x,y)为起点时骑士可能进行的八种移动。一般来说,位于(x,y)的骑士可能移动到以下方格之一:(x-2,y+1)、(x-1,y+2)、(x+1,y+2)、(x+2,y+1)、(x+2,y-1)、(x+1,y-2)、(x-1,y-2)、(x-2,y-1)。但请注意,如果(x,y)的位置离某一条边较近,有些可能的移动就会把骑士移到棋盘之外,而这当然是不允许的。骑士的八种可能的移动可以用一个数组MoveOffset方便地表示出来: MoveOffset[0]=(-2,1) MoveOffset[1]=(-1,2) MoveOffset[2]=(1,2) MoveOffset[3]=(2,1) MoveOffset[4]=(2,-1) MoveOffset[5]=(1,-2) MoveOffset[6]=(-1,-2) MoveOffset[7]=(-2,-1) 于是,位于(x,y)的骑士可以移动到(x+MoveOffset[k].x, y+MoveOffset[k].y),其中k是0到7之间的某个整数值,并且新方格必须仍位于棋盘上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值