已知 A 和 B 均是由整型数据组成的集合,使用顺序表表示集合,设计算法求集合A、B 的交集和并集,功能包括输入集合A,输入集合B,求A和B的并集,求A和B的交集。本题中, 线性表的第一个元素位置为1,线性表的最大长度为20。
输入描述:各个命令以及相关数据的输入格式如下: 输入集合A:A,接下来的一行是要输入的集合元素个数 n ,下面是 n 行数据,每行数据有一个值,代表集合元素值 输入集合B:B,接下来的一行是要输入的集合元素个数 n,下面是 n 行数据,每行数据有一个值。当输入的命令为 U 时,输出 A 和 B 两个集合的并集,当输入的命令为 I 时,输出 A 和 B 两个集合的交集,当输入的命令为 E 时,程序结束。注意,所有的元素均占一行。
输出描述:当输入的命令为 U 时,输出 A 和 B 两个集合的并集(元素从小到大排序输出) 当输入的命令为 I 时,输出 A 和 B 两个集合的交集(从小到大排序输出)。
注意,所有的元素均占一行!
测试输入:
A
5
1
2
3
4
5
B
2
4
6
U
I
E
预期输出:
1
2
3
4
5
6
4
补全如下代码
#include<stdio.h>
int main()
{
int a[20],b[20],c[20],d[40],la=0,lb=0,lc=0,ld=0;
char sel;
while(1)
{
scanf("%c",&sel);
if(sel=='A')
{
//如果读入A,则输入集合A
/***********Begin***********/
/************End************/
}
if(sel=='B')
{
//如果读入B,则输入集合B
/***********Begin***********/
/************End************/
}
if(sel=='U')
{
//如果读入U,则输出集合A和B的并集
/***********Begin***********/
/************End************/
}
if(sel=='I')
{
//如果读入I,则输出集合A和B的交集
/***********Begin***********/
/************End************/
}
if(sel=='E')
return 0;
}
}
还是数组的遍历问题,代码如下:
#include<stdio.h>
int main()
{
int a[20],b[20],c[20],d[40],la=0,lb=0,lc=0,ld=0;
char sel;
while(1)
{
scanf("%c",&sel);
if(sel=='A')
{
//如果读入A,则输入集合A
/***********Begin***********/
scanf("%d",&la);
for(int i=0;i<la;i++)
scanf("%d",&a[i]);
getchar(); //吸收回车符
//数组a排序
for(int i=0;i<la-1;i++)
{
for(int j=0;j<la-1-i;j++)
{
if(a[j]>a[j+1])//从小到大排序
{
ld = a[j];
a[j] = a[j+1];
a[j+1]=ld;
}
}
}
/************End************/
}
if(sel=='B')
{
//如果读入B,则输入集合B
/***********Begin***********/
scanf("%d",&lb);
for(int i=0;i<lb;i++)
scanf("%d",&b[i]);
getchar();
//数组b排序
for(int i=0;i<lb-1;i++)
{
for(int j=0;j<lb-1-i;j++)
{
if(b[j]>b[j+1])//从小到大排序
{
ld = b[j];
b[j] = b[j+1];
b[j+1]=ld;
}
}
}
/************End************/
}
if(sel=='U')
{
//如果读入U,则输出集合A和B的并集
/***********Begin***********/
getchar(); //吸收回车
int i=0,j=0;
lc = 0;
while(i<la && j<lb)
{
if(a[i]<b[j])
{
c[lc] = a[i];
i++;
lc++;
}else if(a[i] == b[j])
{
c[lc] = a[i];
lc++;
i++;
j++;
}else
{
c[lc]=b[j];
j++;
lc++;
}
}
while(i<la)
{
c[lc] = a[i];
i++;
lc++;
}
while(j<lb)
{
c[lc]= b[j];
j++;
lc++;
}
//输出
for(i=0;i<lc;i++)
printf("%d\n",c[i]);
/************End************/
}
if(sel=='I')
{
//如果读入I,则输出集合A和B的交集
/***********Begin***********/
getchar(); //吸收回车
ld = 0;
int i=0,j=0;
for(i=0;i<la;i++)
{
for(j=0;j<lb;j++)
{
if(a[i]==b[j])
break;
}
if(j<lb)
{
d[ld] = a[i];
ld++;
}
}
if(ld == 0)
printf("NULL"); //并集为空时输出NULL,这个题目中没有说明,这里输出NULL
else
{
for(i=0;i<ld;i++)
{
printf("%d\n",d[i]);
}
}
/************End************/
}
if(sel=='E')
return 0;
}
}
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!【相关推荐】
编写回溯算法代码时,要先考虑这个问题是一个什么搜索树,然后套用那个搜索树模板就行了。(例如:子集树就是:判断是否满足约束条件——计算、x[i]=1——递归左子树——归还——x[i]=0、递归右子树(注意限界思想))
(例如:排列树就是:循环——判断是否满足约束条件——交换——计算——递归(注意限界思想)——归还)
当然具体算法要具体分析
还要注意及时更新解和存储解,别忘了进入右子树、循环结束前,要将你算的、交换过的东西,要归还回去。注意到达叶结点干什么,没有到达怎么做
而分支限界算法的代码编写,首先编写三个类:活结点类、活结点属性类、入队类。然后选择好什么样的队列方式。一定要考虑好属性,然后什么时候添加结点、以及出队、和存储最优解
两个算法编写,还要注意限界函数的设置,怎么设计一个好的代价函数可以裁掉更多的空间。这就是两个算法的优化思想。
当然最重要的还要考虑好约束条件。
具体逻辑代码还是多写多练。多去总结。这里也就只讲个大体思路。