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;
}
}
对比效果