第五章习题答案_第五章习题及答案
第五章习题答案由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“第五章习题及答案”。
第5章 集合与结构 5.1 选择题
1.语句cout
(A)0, 0(B)0, 1(C)1, 0(C)1, 1 2.语句cout
(A)0, 0(B)1, 1(C)2, 0(D)3, 1 3.有以下说明语句:
struct point { int x;int y;}p;则正确的赋值语句是(C)。
(A)point.x = 1;point.y = 2;(B)point={ 1, 2 };
(C)p.x = 1;p.y = 2;
(D)p = { 1, 2 };4.已知有职工情况结构变量emp定义为:
struct Date {
int year;int month;
int day;};strnct Employee { char name[20];long code;Date birth };Employee emp;下列对emp的birth正确赋值方法是(D)。
(A)year=1980;month=5;day=1;(B)birth.year=1980;birth.month=5;
birth.day=1;(C)emp.year=1980;emp.month=5;
emp.day=1;(D)emp.birth.year=1980;emp.birth.month=5;
emp.birth.day=1;5.有以下说明语句:
struct Student {
int num;double score;};Student stu[3]={{1001,80}, {1003,91}}, p=stu;则下面引用形式错误的是(B)。(p++)>num(D)(p).num 6.有以下说明语句:
struct Worker {
{1002,75},(A)p>num(B)(p++).num(C)int no;char name[20];};Worker w, p = &w;则下列错误的引用是(D)。
(A)w.no(B)p->no
(C)(p).no(D)p.no 7.s1和s2是两个结构类型变量,若要使赋值s1=s2合法,则它们的说明应该是(C)。
(A)s1只能接收相同类型的数据成员
(B)结构中的成员相同
(C)同一结构类型的变量
(D)存储字节长度一样的变量
5.2 阅读下列程序,写出运行结果。
1.#include using namespace std;struct Data {
int n;
double score;};int main(){
Data a[3] = { 1001,87,1002,72,1003,90 }, p = a;
cout n
cout n
cout n++
cout
1001 1002 1003 1004 2.
#include using namespace std;struct Employee {
char name[ 20 ];
char sex;};void fun(Employee p){ if((p).sex == 'm')
cout
Employee emp[5] = {
int i;
for(i=0;i
fun(emp+i);} 【解答】
'm',“Liming”, “Wangxiaoping”, 'f', “Luwei”, 'm' };
Liming
Luwei 3.
#include using namespace std;struct Node {
char s;
Node q;};int main(){
Node a[ ] = { { “Mary”, a+1 }, { “Jack”, a+2 }, { “Jim”, a } };
Node p = a;
cout s
cout q->s
cout q->q->s
cout q->q->q->s
Mary Jack Jim Mary 5.3 思考题
1.判断一个整数n的奇偶性,可以利用位运算判断吗?请你试一试。【解答】 可以。一个整数当最低位为1时,它是奇数,否则为偶数。以下函数返回对参数k的奇偶判断。
bool odd(int k){ return 1&k;} 2.长度为N的数组可以表示N个元素的集合,若有:
S[i]==1,表示对应元素在集合中
如何实现集合的基本运算?请你试一试。并从内存和处理要求上与5.2.2节中集合的实现方法进行比较。【解答】
长度为N的数组S可以表示有N个元素的集合。当S[i]==1,表示元素i+1在集合中;当S[i]==0,表示元素i+1不在集合中。集合运算通过对数组元素操作完成。
用数组实现集合运算的空间和时间消耗高于用无符号整数和位运算实现集合运算。用数组实现集合运算程序如下。
#include using namespace std;void setPut(unsigned *S);
//输入集合S的元素
void setDisplay(const unsigned *S);
//输出集合S中的全部元素
bool putX(unsigned *S, unsigned x);
//元素x并入集合void Com(unsigned *C, const unsigned *A, const unsigned *B);//求并集C=A∪B void setInt(unsigned *C, const unsigned A, const unsigned B);//求交集C=A∩B
void setDif(const unsigned A, const unsigned B);
//求差集C=A-B bool Inc(const unsigned *A, const unsigned *B);
//判蕴含
bool In(const unsigned *S, const unsigned x);
//判属于x∈S bool Null(const unsigned *S);
//判空集
const int N=32;//输入集合元素 void setPut(unsigned *S){
unsigned x;cin >> x;while(x>0&&x
putX(S, x);//把输入元素并入集合S
cin >> x;} } //输出集合S中的全部元素 void setDisplay(const unsigned *S){
cout
cout
for(int i=0;i
{
if(S[i])
cout
}
cout
} return;} //元素x并入集合S bool putX(unsigned *S, unsigned x){
if(x>0&&x
S[x-1] = 1;
return true;} return false;} //求并集C=A∪B void Com(unsigned *C, const unsigned *A, const unsigned *B){
for(int i=0;i
C[i]= int(A[i] || B[i]);} //求交集C=A∩B
void setInt(unsigned *C, const unsigned *A, const unsigned *B){
for(int i=0;i
C[i]= int(A[i]&&B[i]);} //求差集C=A-B void setDif(unsigned *C, const unsigned *A, const unsigned *B){
for(int i=0;i
C[i]= int(A[i]&&!(A[1]&&B[i]));} //判蕴含,A蕴含于B时返回true bool Inc(const unsigned *A, const unsigned *B){
for(int i=0;i
{
if(A[i]&&!B[i])
return false;
} return true;} //判属于,x∈S时返回true bool In(const unsigned *S, const unsigned x){
return S[x-1];} //判空集,S为空集时返回true bool Null(const unsigned *S){
for(int i=0;i
if(S[i])
return false;} return true;} int main(){
unsigned A[N]={0}, B[N]={0}, C[N]={0};unsigned x;cout
setDisplay(A);cout>x;cout
cout
cout > x;if(In(A, x))
cout
cout
int data;
Node error;//错误
Node ok;//正确 };error和ok分别属于什么数据类型?有什么存储要求?error出错的原因是什么?
【解答】
error是Node结构类型数据成员,错误。原因是结构定义的数据成员若为本身的结构类型,是一种无穷递归。ok是指向Node类型的指针,定义正确,占4字节。
4.本章例5-8中用辅助数组对结构数组进行关键字排序,有定义:
person index[100];index数组存放结构数组元素的地址。如果把index定义改为:
int index[100];用于存放结构数组元素的下标,可以实现对结构数组的索引排序吗?如何修改程序?请你试一试。
【解答】
可以。关键是通过整型索引数组元素作为下标访问结构数组。表示为:
all[pi[i]].name all[pi[i]].id all[pi[i]].salary 有关程序如下:
#include using namespace std;struct person //说明结构类型 {
char name[10];
unsigned int id;
double salary;};void Input(person[], const int);void Sort(person[], int[],const int);void Output(const person[], int[],const int);int main(){
person allone[100];//说明结构数组
int index[100];
//说明索引数组
int total;
for(int i=0;i
index[i]=i;
cout
cin>>total;
cout
Input(allone,total);
cout
Sort(allone,index, total);
cout
Output(allone,index,total);} void Input(person all[], const int n){ int i;
for(i=0;i
{
cout
cin>>all[i].name;
cout
cin >> all[i].id;
cout
cin >> all[i].salary;
} } void Sort(person all[], int pi[], const int n){ int i,j;
int t;
//交换用中间变量
for(i=1;i
{
for(j=0;j
if(all[pi[j]].salary>all[pi[j+1]].salary)//通过索引数组访问结构数组元素
{
t=pi[j];
//交换索引数组元素值
pi[j]=pi[j+1];pi[j+1]= t;
}
} } void Output(const person all[], int pi[], const int n){ for(int i=0;i
cout
struct Node {
int data;
Node next;};void ShowList(Node head){
while(head)
{
cout date
head ++;
} } 【解答】
head++错误,原因是动态链表的结点存放不是连续顺序的内存空间,它们是逐个结点通过new建立的,所以不能用++做地址偏移运算。应该用:
head=head->next;5.4 编程题
1.编写程序,将一个整型变量右移4位,并以二进制形式输出该整数在移位前和移位后的数值。观察系统填补空缺的数位情况。
#include using namespace std;void bitDisplay(unsigned value);int main(){
unsigned x;cout > x;bitDisplay(x);x>>=4;2.数 cout
unsigned c;unsigned bitmask = 1
cout
value
if(c%8 == 0)
cout
unsigned power2(unsigned number, unsigned pow){ unsigned c=1;unsigned bitmask = 1
while(c
{
if(number&bitmask)break;//查找最高位的1即判断c为何值时最高位为1,判断可左移的最大次数
c++;
bitmask>>=1;} if(pow
return number
cout
return 0;} } 3.使用按位异或(^)运算,可以不使用中间变量,快速交换两个变量的值。设计一个函数,实现快速交换两个整型变量的值。【解答】
void Swap(int &A, int &B){
A=A^B;B=A^B;A=A^B;} 4.集合的元素通常是字符。设计程序,用无符号整数表示ASCII码字符集合,用位运算实现各种基本集合运算。【解答】
ASCII码是0~127的整数,可以用长度为4的无符号整型数组表示集合,如教材例5-4所示。区别是,在输入集合元素时,需要把字符转换成整型数据,在输出操作中,把整型集合元素转换成字符型数据。程序略。5.使用结构类型表示复数。设计程序输入两个复数,可以选择进行复数的+、-、×或÷运算,并输出结果。【解答】
#include #include using namespace std;struct complex {
double re, im;
};int main(){ complex a,b,c;char oper;
cout
cin >> a.re >> a.im;
cout
cin >> b.re >> b.im;
cout
cin >> oper;
switch(oper)
{
case '+': c.re=a.re+b.re;c.im=a.im+b.im;break;
case '-': c.re=a.re-b.re;c.im=a.im-b.im;break;
case '*': c.re=a.re*b.re-a.im*b.im;
c.im=a.im*b.re+a.re*b.im;break;
case c.re=(a.re*b.re+a.im*b.im)/(b.re*b.re+b.im*b.im);
c.im=(a.im*b.re-a.re*b.im)/(b.re*b.re+b.im*b.im);
break;
default: cout
return 0;} cout
'/': 【解答】
#include using namespace std;int main(){
struct data { char name[12];
double score;}a[ ] = {“李小平”,90,“何文章”,66,“刘大安”,87,“汪立新”,93,“罗建国”,78,“陆丰收”,81,“杨勇”,85,“吴一兵”,55,“伍晓笑”,68,“张虹虹”,93};
double max = a[0].score;
int i,n = sizeof(a)/ sizeof(data);
for(i=1;i
if(a[i].score > max)max = a[i].score;
for(i=0;i
if(a[i].score == max)cout
} 7.使用结构表示X—Y平面直角坐标系上的点,编写程序顺序读入一个四边形的4个顶点坐标,判别由这个顶点的连线构成的图形是否为正方形、矩形或其他四边形。要求:定义求两个点距离的函数使用结构参数。【解答】
#include #include using namespace std;struct point { double x;double y;};double d(point p1, point p2){
return sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2));
} int main(){
int i;point p[5];
for(i=1;i
{ cout
cin >> p[i].x >> p[i].y;
}
if(fabs(d(fabs(fabs(d(p[1],p[2] d(d(p[1],p[4] p[1],p[3] p[1],p[2]))))
-d(p[3],p[4]))
&& d(p[2],p[3]))
&& d(p[2],p[4]))
if(d(p[2],p[3]))
cout
else cout
else cout
fabs((2)分别统计男、女职工的人数;(3)在链表尾部插入新职工结点;(4)删除指定编号的职工结点;
(5)删除年龄在60岁以上的男性职工或55岁以上的女性职工结点,并保存在另一个链表中。要求:用主函数建立简单菜单选择,并测试程序。【解答】
#include using namespace std;struct employee { int num;
int age;
char sex;
employee *next;};employee *head, *head1;//建立单向链表 employee *create(){ employee *head, *p, *pend;
char ch;
head = NULL;
cout > ch;
if(ch == 'y')
{
p = new employee;
cout > p->num;
cout > p->age;
cout > p->sex;}
else
goto L0;
while(ch == 'y')
{
if(head == NULL)head = p;
else pend->next = p;
pend = p;
cout >ch;
if(ch == 'y')
{
p = new employee;
cout > p->num;
cout > p->age;
cout > p->sex;
}
}
pend->next = NULL;
L0: return head;} //显示单向链表中全部职工信息 void show(employee *head){ employee *p = head;if(!head){ cout
cout
while(p)NULL
{
cout num age sex
p = p->next;
} L1: } //统计男女职工人数 void count(employee *head){ employee *p = head;
int m, f;
m = 0;f = 0;
while(p)
{ if(p->sex == 'm')m++;
else
f++;
p = p->next;
}
cout
cout
employee *insert(employee *&head){
employee *pend = head, *p;
//在空链表尾部插入新结点
if(!head)
{
p = new employee;
cout > p->num;
cout > p->age;
cout > p->sex;
head = p;
p->next = NULL;
return head;}
//在链表尾部插入新结点
while(pend->next!= NULL)
{
pend = pend->next;
}
p = new employee;
cout > p->num;
cout > p->age;
cout > p->sex;
pend->next = p;
pend = p;
pend->next = NULL;
return head;} //删除指定编号的结点
employee *del(employee *&head,int bh){
employee *p, *q;
if(!head)
{
cout
goto L2;
}
//删除链首结点
if(head->num == bh)
{
p = head;
head = head->next;
delete p;
cout
goto L2;}
//删除非链首结点
q = head;
while(q->next!= NULL)
{
if(q->next->num == bh)
{
p = q->next;
//待删除结点
q->next = p->next;
delete p;
cout
goto L2;
}
q = q->next;
}
cout
employee *delcreate(employee *&head){ employee *p, *pd, *p1, *q;
int flag;
//建立新链表
if(head == NULL)
{
cout
goto L3;}
head1 = NULL;
pd = new employee;
p = head;
flag = 0;
while(p!= NULL)
{
if(p->age >= 55 && p->age
{
pd->num = p->num;
pd->age = p->age;
pd->sex = p->sex;
if(head1 == NULL)
head1 = pd;
else
p1->next = pd;
p1 = pd;
pd = new employee;
flag = 1;
}
p = p->next;
}
if(flag == 0)
{ cout next = NULL;//显示新链表
cout num age sex
p = p->next;} //删除指定年龄的结点 p = head;q = p;while(p!= NULL){ if(p->age >= 55 && p->age
if(head->age == p->age)
{
pd = head;
//待删除结点
head = head->next;
点
delete pd;p = head;continue;} else if(p->next == NULL){
pd = p;
q->next = NULL;
delete pd;
goto L3;
} else {
pd = p;
q->next = p->next;
//待删除结
//待删除结点
delete pd;p = q->next;continue;} q = p;p = p->next;
}
L3: return(head);} int main(){ int choice, bh;L: cout
cout
cout
cout
cout
cout
cout
cin >> choice;
switch(choice)
{
case 1 : head = create();goto L;
case 2 : show(head);goto L;
case 3 : count(head);goto L;
case 4 : head = insert();goto L;
case 5 : cout
cin >> bh;
head = del(bh);goto L;
case 6 : head = delcreate();goto L;
case 0 : cout
default : cout
} } 9.输入一行字符,按输入字符的反序建立一个字符结点的单向链表,并输出该链表中的字符。
【解答】
#include using namespace std;struct node { char ch;
node *next;
};void show(node *head);int main(){ node *head, *p;
char c;
head = NULL;
while((c = getchar())!= 'n')//输入一行字符
{
p = new node;
//建立新结点
p->ch = c;
p->next = head;
//插入表头
head=p;
}
show(head);} void show(node *head)
表
{ node *p = head;
cout
while(p)
{ cout ch;
p = p->next;
}
cout
struct List { int data;List next;};
//输出链
List head;head是有序单向链表的头指针。请编写函数:
void Count(List head);计算并输出链表数据相同值的结点及个数。例如,若数据序列为:3 3 3 4 5 5 6 6 6 6 7 8 9 9 则输出结果为:
data number 3 3 5 2 6 4 9 2 请用本章例5-11的程序生成有序链表,测试Count函数。
【解答】 略
11.用带头结点的有序单向链表可以存放集合,如图5.16所示。头结点不存放集合元素,仅为操作方便而设置。使用这种数据结构,设计集合的输入、输出和各种基本运算的函数。
图5.16 带头结点的有序单向链表
【解答】 略