西安交大C++程序设计第四章作业2.docx
《西安交大C++程序设计第四章作业2.docx》由会员分享,可在线阅读,更多相关《西安交大C++程序设计第四章作业2.docx(30页珍藏版)》请在冰点文库上搜索。
西安交大C++程序设计第四章作业2
西安交大C++程序设计第四章作业2
西安交通大学实验报告
课程__计算机程序设计__实验名称__结构体__第1页共29页
系别__________实验日期2014年4月26日
专业班级______组别_____________实验报告日期2014年4月27日
姓名__________学号__报告退发(订正、重做)
同组人_________________________________教师审批签字
一、实验目的
掌握结构体的使用方法,学会用结构体的方法定义变量并对变量进行处理;掌握枚举法的使用方法。
二、实验内容
(一)第一题:
1、输入某小组5个人的姓名、性别、出生年份等信息,统计男女人数以及1988年以后(含1988年)出生的人数。
1.源程序代码:
//输入某小组个人的姓名、性别、出生年份等信息,统计男女人数以及年以后(含年)出生的人数。
#include
usingnamespacestd;
structxinxi
{
charname[20];
charsex;
intyear;
};//定义结构体xinxi,包含名称(字符串)、性别(字符)、出生时间(整数)三个变量
intmain()
{
xinxicy[5];
inti,s=0,m=0;
for(i=0;i<5;i++)
{
cout<<"请输入第"<
\n姓名:
";
cin>>cy[i].name;
cout<<"性别(男的输入“b”,女的输入“g”):
";
cin>>cy[i].sex;
cout<<"出生年份:
";
cin>>cy[i].year;
}
cout<<"您输入的是:
\n";
for(i=0;i<5;i++)//显示输入内容
cout<for(i=0;i<5;i++)//统计男女、之后个数
{
if(cy[i].sex=='b')
s++;
if(cy[i].year>=1988)
m++;
}
cout<<"其中男生人数为:
"<
"<<5-s<cout<<"1988年以后(含)出生的的人数为:
"<return0;
}
2.实验结果:
3.问题分析:
略。
(二)第二题:
读入五个用户的姓名和电话号码,按照姓名的字典顺序排列后,输出用户的姓名和电话号码。
1.源程序代码:
//读入五个用户的姓名和电话号码,按照姓名的字典顺序排列后,输出用户的姓名和电话号码。
#include
#include
usingnamespacestd;
structdianhuabu
{
charname[30];
charnum[15];
};//定义结构体dianhuabu,包含两个变量:
名字和电话号码。
由于电话号码较长又无需对其进行具体处理,故定义为字符串型
intmain()
{
dianhuabudhb[5];//声明dianhuabu型变量
inti;
for(i=0;i<5;i++)
{
cout<<"请输入第"<
\t姓名:
";
cin>>dhb[i].name;
cout<<"电话号码:
";
cin>>dhb[i].num;
}
cout<<"您输入的信息如下:
\n";
for(i=0;i<5;i++)//显示输入信息
{
cout<}
for(i=0;i<5;i++)//排序
{
intk=i;
for(intj=i+1;j<5;j++)
if(strcmp(dhb[j].name,dhb[k].name)<0)//用库函数strcmp比较字符串大小
k=j;
if(k!
=i)
{
dianhuabutmp=*(dhb+i);//定义dianhuabu型变量tmp作为中间变量,进行交换
*(dhb+i)=*(dhb+k);
*(dhb+k)=tmp;
}
}
cout<<"排序结果如下:
\n";
for(i=0;i<5;i++)
cout<return0;
}
2.实验结果:
(1)随机输入名称:
(2)输入名称长度递增,后者包含前者,用来检验库函数strcmp的排序效果:
3.问题分析:
略。
(三)第三题:
输入两个整型数组(假设数组的大小为7)的各个元素,输出不是两个数组共有元素,例如,输入1,2,3,4,5,6,7和5,6,7,8,9,0,输出为1,2,3,4,8,9,0.
1.源程序代码:
//输入两个整型数组(假设数组的大小为7)的各个元素,输出不是两个数组共有元素,
//例如,输入1,2,3,4,5,6,7和5,6,7,8,9,0,输出为1,2,3,4,8,9,0.
#include
usingnamespacestd;
intmain()
{
inta[7],b[7],c[14];
inti,j,m=0;
cout<<"请输入数组a的每个元素:
\n";
for(i=0;i<7;i++)
cin>>*(a+i);
cout<<"请输入数组b的每个元素:
\n";
for(j=0;j<7;j++)
cin>>*(b+j);
for(i=0;i<7;i++)
{
j=0;
while(*(a+i)!
=*(b+j)&&j<7)
j++;
if(j==7)
{
*(c+m)=*(a+i);
m++;
}
}
for(i=0;i<7;i++)
{
j=0;
while(*(b+i)!
=*(a+j)&&j<7)
j++;
if(j==7)
{
*(c+m)=*(b+i);
m++;
}
}
if(m==0)
{
cout<<"没有非共有元素!
\n";
return0;//直接结束,不再进行以下内容
}
cout<<"共有"<\n";
intk;
for(k=0;kcout<<*(c+k)<<"";//输出
cout<return0;
}
2.实验结果:
(1)全不相同:
(2)部分相同:
(3)全相同:
3.问题分析:
不足之处:
题目中说是数组大小为7,但第二个数组只有六个元素也进行了比较。
而我的作业中没有实现这一点,只能是7个元素.
(四)实验题目四:
口袋中有红、黄、蓝、白、黑5种颜色的小球若干个,如果每次都从口袋中取出3种不同颜色的小球,共有多少种组合?
试打印出每种组合的3种颜色,要求使用枚举类型来表示小球的颜色。
1.程序源代码
#include
usingnamespacestd;
enumColors{red,yellow,blue,white,black};
voidys(inti)
{
switch(i)
{
casered:
cout<<"red";
break;
caseyellow:
cout<<"yellow";
break;
caseblue:
cout<<"blue";
break;
casewhite:
cout<<"white";
break;
caseblack:
cout<<"black";
break;
}
}
voidmain()
{
ints=0,i,j,k;
for(i=red;i<=blue;i++)
for(j=1+i;j<=white;j++)
for(k=j+1;k<=black;k++)
{
s++;
ys(i);
ys(j);
ys(k);
cout<}
cout<<"总共的组合数为:
"<
}
2.实验结果
3.问题分析:
此题中虽然定义了枚举类型,然而实际过程中,感觉并没有使用到枚举,它的存在似乎没有意义,不知道是不是方法用错了。
五、第五题:
5、编写函数,该函数实现任意一个正整数是否为完全数。
再编写函数输出完全数等于各因子之和的式子。
最后找出2~100000之内所有完全数。
所谓完全数是其各因子之和正好等于本身的数,例如输出格式如下的完全数:
6=1+2+3,28=1+2+4+7+14。
#include
usingnamespacestd;
voidpanduan(inti)//自定义函数,用于判断i是不是完全数
{
intm,s=0;
int*num=newint[i];//动态分配数组空间,虽然仍然大于实际需要值,但数组大小基本上得到了控制
for(m=1;m<=i/2;m++)
{
if(i%m==0)
{
num[s]=m;
s++;//s最终为因子个数
}
}
intsum=0;
intn;
for(n=0;n
sum=sum+num[n];//sum最终为各因子之和
if(sum==i)
{
cout<
for(n=0;ncout<cout<}
delete[]num;//释放数组空间
}
intmain()
{
inti;
cout<<"从2到的100000完全数如下:
\n";
for(i=2;i<100000;i++)
panduan(i);
return0;
}
2.实验结果:
3.问题分析:
在做这道题的过程中,起初出现了一个奇怪的现象:
如果上限由100000改为10000,则程序正常运行,但对于100000,会显示出现问题:
后来检查不出问题时,发现了一直以来一个不良习惯:
不编写释放数组空间的语句。
试着加上这一语句之后再运行时,发现程序能够正常进行了,因而认为应该是这句语句的作用,但并不知道具体的原因。
六、第六题:
6、(必做题)编写一个实现文章(即字符串)单词统计功能的程序,要求:
输入一系列英文单词字符串(即带空格的字符串),单词间用空格隔开或逗号或句号隔开。
请统计该字符串中单词出现的频率,并按词典顺序输出单词及其频率。
必须用结构体方法实现。
1.源程序代码:
#include
#include
usingnamespacestd;
structfrequency
{
charword[20];
intn;
}danci[100];//定义结构体变量danci,它由单词及其频率两个量组成
structw
{
chara[20];
}in[100];//定义了个元素的字符串组,用于储存输入的句子中的每个单词
intfre(charnu[],win[],intmu)//统计每个单词的频率函数
{
inti,pl=0;
for(i=0;i{
if(strcmp(nu,in[i].a)==0)
pl++;
}
returnpl;
}
voidmain()
{
chararticle[501];
cout<<"输入句子:
\n";
cin.get(article,500);
intl=strlen(article);//取其长度,定义为整型数l
inti,j,k,m;
for(i=0,j=0;i离开单词部分到进入单词部分之间的字符
{
chara=*(article+i);//a定义为article第i个字符,
if((a<='z'&&a>='a')||(a<='Z'&&a>='A'))//判断若已经是字母了的话就进入循环记录接下来的单词内容,否则继续i增加直到走完非字母字符到达字母
{
m=0;
k=i;
charb=*(article+k);
while((b<='z'&&b>='a')||(b<='Z'&&b>='A'))//当它是字母就循环,若已经不是字母了,就跳出循环
{
in[j].a[m]=b;
k++;
m++;
b=*(article+k);
};//一直加直到遇到非字母字符时停止
in[j].a[m]='\0';//这个单词转录完了之后,将最后一个字符写为‘\0'以防乱码
j++;//下一个单词的写入
i=k-1;//由于在小循环中k最后一次循环多加了一个,所以在这里扣除,赋给i,i就不再执行单词的中间字母部分,只需对非字母部分判断直到遇到下一个单词的开头字母
}
}//至此,已记录所有单词到in[].a中。
intmu=j;//记录下单词数目,共有单词mu个(注意到最后j加了)
//然后将每一个不同的单词储存在danci[].word里
ints=0;
for(i=0;i{
j=0;
while(j
=0)
j++;
if(j==i)
{
strcpy(danci[s].word,in[i].a);
s++;
}
}//至此将所有不同单词依次储存到了danci.word中,s为不同单词个数
//然后排序
for(i=0;i
{
k=i;
for(j=i+1;j
if(strcmp(danci[j].word,danci[k].word)<0)
k=j;
if(k!
=i)
{
frequencytmp=*(danci+i);
*(danci+i)=*(danci+k);
*(danci+k)=tmp;
}
}
//
cout<<"统计结果为:
\n";
for(i=0;i
{
danci[i].n=fre(danci[i].word,in,mu);
cout<<"单词:
"<"<}
}
2.实验结果:
(1)按照题目要求的检验:
(2)事实上,由于审题失误,我所编写的这个程序,能够对一切情况进行处理(个人认为这个程序能够实现题目的要求,所以不能算错),单词之间可以有多个非字母字符,可以有空格,开头也可以有各种字符,唯一不足的是无法将The和the识别为同一单词:
3.问题分析:
这道题较难,再加上审题的失误导致我在这道题上做了更多的工作。
可能办法有点笨,但没有深入思考,所以最终程序较为麻烦。
从我最终编写的程序来看,能够实现对各种输入情况下单词数的统计,实现这一功能主要问题在以下几点:
首先说明程序的思路:
输入一个含有各种字符的字符串,然后将其中的每一个单词依次挑选出来同时将其储存在用结构体定义好的一组字符串中;然后将这些单词中不同的单词挑出来存到另一二元结构体{单词,频率}的每一项的“单词”元素中;然后对二元结构体根据“单词”元素进行排序;然后根据每个“单词”元素在原来储存的所有单词中的出现次数得到频率并且同时将频率值保存到“频率”元素中并输出。
(1)单词的分离过程,这应该是其中几乎最麻烦的过程。
由于要将每个单词识别出来,分开并且储存下来所以要定义一系列的字符串用于存储每个单词,为此定义了结构体:
structw
{
chara[20];
}in[100];
然后需要判断单词。
从第一个字符开始,遇到字母后开始将原字符串的字符录入到单词字符串,遇到不是字母的字符时停止,给末尾加上’\0’后这一单词的录入便完成,然后从这个非字母字符开始在往下判断,遇到下一个字母也就是下一个单词的首字母时子进行下一个单词的录入,直到完成所有录入。
完成以上工作之后,为了进行下一步的统计频率,还需要将其中不同的单词挑出来然后存储到二元结构体的Word元素中,为此进行如下操作:
从第一个单词开始,逐个判断它是不是与前面所有单词都不相同,若是,则将其存储下来,否则不存储。
为此用了库函数strcmp进行两个字符串之间的比较。
(2)排序:
这一环节比较简单,完全可以仿照作业第二题的方法;
(3)频率统计:
将存储下来的不同单词依次在所有单词中找出与之相同的个数即可,由于之前已经完成,故可以在记录频率同时输出结果。
(4)不足:
用到库函数strcmp时,程序有警告,但可以运行,至于警告的原因,尚不清楚。
(七)第七题:
7、(必做题)任意输入一个正整数,统计输出各个数位上数字出现的次数。
例如输入312366060,输出0为2;1为1;2为1;3为2;6为3。
1.源程序代码:
#include
usingnamespacestd;
structfrequency
{
intm;//数字
intn;//频率
};
intmain()
{
intx;//输入的数
cout<<"请输入整数:
";
cin>>x;
inta,i,j,k,s=x;//s初始为输入值,后逐渐缩小,用于求解位数;a得到的是位数
for(a=0;s>0;a++)
s=s/10;
int*num=newint[a];
for(i=0,s=x;i{
*(num+i)=s%10;
s=s/10;
}
frequencyfre[10];
for(j=0;j<=9;j++)
{
k=0;
for(i=0;i<=a;i++)
{
if(j==num[i])
k++;
}
fre[j].n=k;
fre[j].m=j;
}
cout<<"统计结果如下:
\n";
for(j=0;j<10;j++)
{
if(fre[j].n!
=0)
cout<}
return0;
}
2.实验结果:
(1)开头不是0:
(2)开头是0,由于是输入正整数,所以开头的0不考虑:
3.问题分析:
思路:
(1)求出整数位数,以便动态分配数组空间;
(2)依次分离出每一位的数存储下来;
(3)从0到9逐个统计个数;
(4)对于个数为0的不输出,大于0的输出统计结果。
八、第八题:
8、(选作题)第一将整数翻译程序中翻译千位整数的函数直接屏幕输出英文改为形成翻译字符串返回给主调函数;第二将子串个数统计程序改为使用库函数strncmp()来实现。
1.源程序代码:
(1)
#include
#include
usingnamespacestd;
staticchar*gewei[]=
{
"",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen"
};
staticchar*shiwei[]=
{
"",
"",
"twenty",
"thirty",
"forty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety"
};
char*m(inta)
{
intb=a%100;
charoutput[50]="";
if(a/100!
=0)
{
strcat(output,gewei[a/100]);
strcat(output,"hundred");
if(b!
=0)
strcat(output,"and");
}
if(b<20)
strcat(output,gewei[b]);
else
{
strcat(output,shiwei[b/10]);
if(b%10!
=0)
{
strcat(output,gewei[b%10]);
}
}
returnoutput;
}
voidmain()
{
intn;
charstr[200]="";
cout<<"请输入n:
";
cin>>n;
inta=n/1000000,b=(n%1000000)/1000,c=n%1000;
if(a!
=0)
{
strcat(str,m(a));
strcat(str,"million");
}
if(b!
=0)
{
strcat(str,m(b));
strcat(str,"thousand");
}
if(c!
=0)
{
if(c<100)
strcat(str,"and");
strcat(str,m(c));
}
cout<}
(2)
#include
usingnamespacestd;
intcount(char*pi,char*pj)
{
intnum=0;
char*pt=pi;
intpjn=strlen(pj);
while(*pt!
='\0'&&strlen(pt)>