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;
}