实验二2.1 打印温度柱状图 2.2 处理零下温度

1)问题描述
下图是某城市15天的气温变化曲线。其中标注为A的地方称为峰点,标记为B的地方称为谷点,而标记为C的地方称为崮。要求编写1个函数输入15天的气温,然后通过3个函数分别实现下述功能:
(1)打印每天温度的柱状图(仅考虑温度为正值的情况)。
(2)打印所有峰点的位置(该月的第几天)及峰值。如果没有,则打印没有峰值。
(3)打印最长的崮的长度。只使用一重循环即可求出。
在这里插入图片描述
(2)问题要求
请实现以下函数声明,要求能得到如下图所示的运行结果。
在这里插入图片描述

在这里插入图片描述

这是主函数以及声明的一堆函数
因为以及有了规定了,所以就没有做什么改动
各个函数功能也都在题目要求上说了 所以就不说了

#include<iostream>
#include<algorithm>
const int N = 30;
char ch;
using namespace std;
void inputTemps(int temps[], int n);
void displayTemps(int temps[], int n);
void displayPeaks(int temps[], int n);
void displayFlat(int temps[], int n);
int main()
{
	int temps[30] = { 0 };
	inputTemps(temps, N);
	displayTemps(temps, N);
	displayPeaks(temps, N);
	displayFlat(temps, N);
}

看第一个子函数inputTemps
遇到的问题是如何输入有限个数以后 通过回车停止输入
一开始没怎么想就用cin.get()==’\n’当遇到\n就弹出 开始因为我们定义的数组是整型数组‘\n’不能进入缓冲流
然后就设置了一个char ch;
用一个do while循环 先输入数字存到temp[i]中,然后输入的空格被ch拿到 如果数字后发现的是回车,那么就跳出循环

void inputTemps(int temp[], int n)
{
	cout<<"please input the tempratures"<<endl;
	char ch;
	/*for (int i = 0; i < N; i++)
	{
		cin >> temp[i];
		if (cin.get()=='\n')
			break;
	}*/
	int i = 0;
	do
	{
		cin >> temp[i];
		ch = cin.get();
		i++;
	} while (ch != '\n');
}

第二个子函数displayTemps
因为题目上要求了都是正数

void displayTemps(int temps[], int n)
{
	cout << "显示柱状图如下:" << endl;
	for (int i = 0; i < N; i++)
	{
		if (temps[i] <= 0)//其实可以用num存住输入截至的值 
		//但是当时没改反正也不错
		//当temp为零的时候就弹出(开始的时候对temp全体赋值为0)
			break;		
		if(i+1<10)
			cout << i+1 << "    ";//这其实是在控制格式,两位数的时候少输出一个空格
		if(i+1>=10)
			cout << i + 1 << "   ";
		for (int j = 0; j < temps[i]; j++)
			cout << "*";//然后输出temps[i]个星星
		cout << endl;
	}
}

第三个函数displayPeaks

void displayPeaks(int temps[], int n)
{
	int pre = 0;//储存当前值,一直比i小一个
	int countt = 0;//储存峰值数目
	cout << "显示峰值如下" << endl;
	for (int i = 1; temps[i]!=0; i++,pre++)
	{
		if (temps[pre] < temps[i])//首先是当前比峰值小
		{
			pre++;//到达峰值
			i++;
			if (temps[pre] > temps[i])//峰值比下一个大
			{
				if (temps[i] == 0)//如果出现0就弹出了
					break;
				cout << "Max at day " << pre+1 << "is" << temps[pre]<<endl;//输出峰值信息
				countt++;//有一个峰值就加一个
			}
			pre--;//必须让pre和i回到上一个值 不然会漏掉
			i--;
		}
	}
	if (countt == 0)//如果没有countt记录那么就输出0
		cout << "没有峰值" << endl;
}

第四个函数displayFlat
maxx = *max_element(days,days+30);//查找days函数中的最大值
max_element和min_element

void displayFlat(int temps[], int n)
{
	int pre = 0;//pre是当前值
	int countt = 1;//因为连续是只要有东西就是1嘛
	int days[30] = {0};//储存岗的长度
	int k=0;//k是days的下标
	int maxx;//最长天数
	cout << "显示岗的长度如下:" << endl;//懒得查怎么读了…
	for (int i = 1; temps[pre] != 0; i++, pre++)//循环
	{
		while (temps[pre] == temps[i])//在相等的时间
		{
			countt++;//countt加一
			pre++;
			i++;
		}
		days[k] = countt;//存入这个countt的值
		k++;
		countt = 1;//让countt回到1 从头开始循环
	}
	
	maxx = *max_element(days,days+30);//查找days中的最大值
	cout << "The length of longest flat is " << maxx << endl;
	cout << "Press any key to continue";
}

漏了一个分号哈 没啥事就这样吧 加上就行
在这里插入图片描述
over
exp2.2 处理零下温度
(1)要求柱状图能够处理多个零下温度的情况,以如下形式打印。(10分)

(2)求出现次数最多的温度,及其出现次数。(10分)
例如:12 13 12 12 14 13 13 12 13 13 中,出现次数最多的是13度,出现了5次。
这个题就很友好了 没有那么多条条框框
先交代一下用到的函数头文件预处理啥的
其实和上一个实验差不离

#include<iostream>
#include<algorithm>
using namespace std;
int num;//数组中有效值的个数
const int N = 30;
void temp_input(int temp[], int n);
void temp_output(int temp[], int n);
void temp_most(int temp[], int n);
struct most_temp//用来查找众数的
{
	int countt;
	int most_num;
};
bool com(most_temp a, most_temp b)//用来排序的
{
      return a.countt > b.countt;
}
int main()
{
	int temp[100];
	temp_input(temp, N);
	temp_output(temp, num);//这里传的就不是N了就是num了
	temp_most(temp, num);
}

第一个函数temp_input

void temp_input(int temp[], int n)
{
	temp[100];
	int i = 0;
	char ch;
	do
	{
		cin >> temp[i++];
		ch = cin.get();//

	} while (ch != '\n');
	num = i;//是一样的最后又存了一下这个num的值
	//for (int k = 0; k < num; k++)
	//	cout << temp[k];
}

第二个函数temp_most
功能是为了查找众数
遇到的问题只能输出一组众数以及他所对应的值
但如果遇到两个以上众数就只能输出第一个,其他的就无能为力了
下面贴一下功能不全的代码

void temp_most(int temp[], int n)
{
	sort(temp, temp + num);//先排序,从小到大(其实无所谓)
	int countt = 1;
	int k = 1;//k下标赋的值为1
	//反正后面要重新排序 无所谓放在哪,为了防止下标越位 就让k赋初值1了
	int max[10] = {0};
	int most_num=0;

	for (int i = 0; i < num-1; i++)
	{
		while (temp[i] == temp[i + 1])//连续
		{
			countt++;
			i++;
		}
		if (countt != 1)//countt==1不需要存 浪费
		{
			if (countt > max[k-1])//把众数对应的值付到most_num上
			{
				most_num=temp[i];
			}
			max[k] = countt;//赋值 重复
			k++;
		}
		countt=1;
	}
	sort(max, max + 9, com);//排序从大到小
	//直接输出第0个就行
	/*for (int i = 0; i < 10; i++)
		cout << max[i];*/
	if (max[0] == 1 || max[0] == 0)
		cout << "无众数" << endl;//要是1或是0的话就没有众数(好像不加1也行 刚刚跳过1了来着)
	else
		cout << "出现最多的是"<<most_num<<"度,出现了"<<max[0]<<"次。";
		//缺点是只能输出一次
}

上面的缺点是众数以及他所对应的值是不相关的
下面是改进的 加了一个结构体
结构体在最上面

void temp_most(int temp[], int n)
{
	sort(temp, temp + num);
	int countt = 1;
	int k = 1;
	struct most_temp max[10];//定义这么十个结构体叫max
	int most_num=0;
	for (int i = 0; i < num - 1; i++)
	{
		while (temp[i] == temp[i + 1])
		{
			countt++;
			i++;
		}
		if (countt != 1)
		{
			max[k].most_num = temp[i];
			max[k].countt = countt;//直接赋值,不用比来比去了(给结构体赋值)
			k++;
		}
		countt = 1;
	}
	int q = 0;
	sort(max, max + 9, com);//降序对结构体排序
	if (max[0].countt == 1 || max[0].countt == 0)
		cout << "无众数" << endl;
	else
	while (max[q].countt == max[0].countt)//如果前几个众数相同都是最大的,就都输出呗!
	{
		cout << "出现最多的是" << max[q].most_num << "度,出现了" << max[q].countt << "次。"<<endl;
		q++;
	}
}

最后一个函数temp_output
输出

void temp_output(int temp[], int n)
{
	char outt[50] ;//输出的那一溜
	
	for (int i = 0; i < num; i++)
	{
		for (int i = 0; i < 50; i++)
			outt[i] = ' ';//必须要都赋值上空格,不然输出乱码
		outt[20] = '|';//因为题里也没说最低温度是多少 随便假设一下最低温度就-19左右把,那把中间0值放在20的位置
		if (temp[i] < 0)//负数,就从19开始倒着输出
			for (int j = 19; j > 19 + temp[i]; j--)
			{
				outt[j] = '*';
			}
		if (temp[i] > 0)//正数,就从21开始正着输出
			for (int k = 21; k < 21 + temp[i]; k++)
			{
				outt[k] = '*';
			}
		cout.width(2);//控制下面一个格式输出
		cout << temp[i];
		for (int j = 0; j < 50; j++)
			cout << outt[j] ;//输出outt数组
		cout << endl;
	}
}

修改了最后这个函数,把固定的outt数组改成动态的,好看一点

void temp_output(int temp[], int n)
{
	int min=*min_element(temp,temp+n);//找到数组中的最小值
	min=abs(min);//取绝对值
	/*cout << min;*/
	char outt[50] ;
	int i = 0, j = 0;
	for (i = 0; i < num; i++)
	{
		for (int i = 0; i < 50; i++)//先初始化为空格
			outt[i] = ' ';
		outt[min + 2] = '|';//保证输出最小负数,前空两格
		if (temp[i] < 0)
			for (j = min + 1; j > min + 1 + temp[i]; j--)
			{
				outt[j] = '*';
				
			}
		if (temp[i] > 0)
			for (int k = min+3; k < min + 3 + temp[i]; k++)
			{
				outt[k] = '*';
			}
		cout.width(3);
		cout << temp[i];
		for (int j = 0; j < 50; j++)
			cout << outt[j] ;
		cout << endl;
	}
}

对比效果
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值