练习7-4 找出不是两个数组共有的元素

练习7-4 题目:找出不是两个数组共有的元素
https://pintia.cn/problem-sets/12/problems/318
因为看到网上都是双重循环遍历查找
题解1
题解2
看到的题解代码普遍长,看到的都是40行以上的代码,没能看到舒适的解答,当然我的思路也不行.
思路:
开一个很大的数组,把所有元素赋初值为0.
如果读入了数据5,50,100,
那么依次标记 a[5],a[50],a[100].(元素的下标和读入的值相等).
但是问题出现了,如果需要读入数据 -5,则需要标记a[-5].
但是数组没有负下标.
解决:
使用对称思想,如果a[100],那么下标0-49存数字-50——0,下标50-99,存数字0-50,那么 读入 数据 -1,1时,
标记a[-1+50]和a[1+50]即可(50是100的一半)
下面是代码:

#include
#define M 500000   //M的长度为数组长度的一半
int a[1000000],order[41];  //数组的元素很多,所以数组要在全局变量中定义
int main()      //order数组用于表示 元素的输入顺序,第一个输入的数组元素存在order[0],第n个输入的数组元素存在order[n-1].
{
     	int m,n,x,i,head=0;
	scanf("%d",&m);
	while(m--)   //读入m个数据
		{
     
		scanf("%d",&x);
		order[head++]=x;
		a[x+M]=3;    //第一次存入数组时,把数值赋为3  
		}
	scanf("%d",&n); 
	while(n--)//读入n个数据
		{
     
		scanf("%d",&x);
		order[head++]=x;
		if(a[x+M]==3)  //表示上次已经存入数组了.把数值改为2
			a[x+M]=2;    
		if (a[x+M]==0) //表示上一次没有读到该数字
			a[x+M]=1;
		}
 
  int cnt=0;//cnt用于控制格式
	for(i=0;i<head;i++)
	{
                                                //如果数值为1,表示在第二次出现了,第一次没出现
		if( a[order[i]+M]==1||a[order[i]+M]==3) //如果数值为3,表示在第一次出现了,第二次没出现
			{
       
			if(!cnt) printf("%d",order[i]); 
			if(cnt) printf(" %d",order[i]);
			cnt++;
			a[order[i]+M]=0;//已经出现过一次,取消标记
			}	
	}
}

下一次再用结构或者友元来优化~

你可能感兴趣的:(PTAC语言程序设计,c语言)