一道笔试题:删除两个整型数组的交集

matrix2009 2009-03-04 05:23:44
如题,删除两个整型数组A和B的交集,要求是,假如A数组有3个1,B数组有2个1,则删除B数组的两个1.
要注意代码的质量。
我当时笔试时考虑的不全面,程序有bug.
我想知道大家会怎么做。尤其是两个数组大小不一时怎么办
我当时的想法是先排序,然后遍历两个数组,找到相同元素,比较相同元素的个数,将个数少的删除之。
大家怎么作呢?
...全文
819 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
chin_chen 2009-03-05
  • 打赏
  • 举报
回复
简单说下:
用一个set建一个两个数组合集,再建一个A数组的set,做差就可以了。
hyldream 2009-03-05
  • 打赏
  • 举报
回复
看过了~~
WizardOz 2009-03-05
  • 打赏
  • 举报
回复
没弄懂题目。
qinqinhao 2009-03-05
  • 打赏
  • 举报
回复
ding
xuhb95083023 2009-03-05
  • 打赏
  • 举报
回复
有点问题,修正下


#include <iostream>
#include <stddef.h>
#include <stdlib.h>
#include <string>
#include <iterator>
#include <algorithm>
#include <vector>

using namespace std;

template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
OutputIterator delete_intersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, OutputIterator dest)
{
while (first1 != last1 && first2 != last2) {
if (*first1 > *first2) {
*dest = *first2;
++first2;
++dest;
} else if (*first1 < *first2) {
*dest = *first1;
++first1;
++dest;
} else {
++first1;
++first2;
}
}

// for (;first1 != last1; ++first1) *dest = *first1;
for (;first2 != last2; ++first2) *dest = *first2;

return dest;
}

int main() {
int a[] = {1,1,2,2,5,6,9,9};
int b[] = {1,2,3,4,4,6,7,8,9,9,9,10};

vector<int> vc;

delete_intersection(a, a + sizeof(a)/sizeof(a[0]), b, b + sizeof(b)/sizeof(b[0]), back_inserter(vc));

std::copy(a, a + sizeof(a)/sizeof(a[0]), ostream_iterator<int>(cout, ",")); cout << endl;
std::copy(b, b + sizeof(b)/sizeof(b[0]), ostream_iterator<int>(cout, ",")); cout << endl;
std::copy(vc.begin(), vc.end(), ostream_iterator<int>(cout, ",")); cout << endl;

::system("PAUSE");
return EXIT_SUCCESS;

}

八级程序员 2009-03-05
  • 打赏
  • 举报
回复
以下为基础薄弱的人参考~ 哈哈~ 在我掌握的水平上解决问题!没有什么学习性!26楼那个我的水平卡不明白阿~555~~~

我太菜拉



#include <iostream>
using namespace std;

class strout
{
public:
strout(string s1)
{
cout <<s1<<endl;
}
void show()
{

}
};


int main()
{
string s = "代码请用插入工具!";
strout so(s);

int a[] = {1,1,2,2,5,6,9,9};
int b[] = {1,2,3,4,4,6,7,8,9,9,9,10};
int c[20] = {0};

int x = sizeof(a)/sizeof(a[0]);
int y = sizeof(b)/sizeof(b[0]);
int i = x - y;

if(i>=0)
{
strout so("a>=b");
// 省略看下面
}
else
{
strout so("a<b");
// 求交集
for(int i = 0;i<x;i++)
for(int j=0;j<y;j++)
{
if (a[i] == b[j])
{
c[i] = a[i];
}
}

}
// 交集中 去掉重复项,这里 置‘0’
for (int i=0;i< 19;i++)
{
for(int j =i+1;j<19;j++)
{
if (c[i]==c[j])
{
c[j]=0;
}
}
}

// 无关紧要
for (int i=0;i<20;i++)
{
cout<<c[i]<< "";
}
cout <<endl;

// 判断交集元素的个数,对个数多的数组置‘0’;
for (int i=0;i<20;i++)
{
// 过滤 C数组中的零
if(c[i]==0)
continue;

int ai = 0;
int bi = 0;

cout<<"c[i]="<<c[i]<<endl;
for (int j =0;j<x;j++)
{
if ((c[i]==a[j])&&(c[i]!=0))
{
ai ++;
}
}
cout<<"ai="<<ai<<endl;
for (int j =0;j<y;j++)
{
if ((c[i]==b[j])&&(c[i]!=0))
{
bi++;
}
}
cout<<"bi="<<bi<<endl;

if (ai>bi)
{
for (int j =0;j<x;j++)
{
if ((c[i]==a[j])&&(c[i]!=0))
{
a[j]=0;
}
}
}
if((ai<bi)&&(c[i]!=0))
{
for (int j =0;j<y;j++)
{
if ((c[i]==b[j])&&(c[i]!=0))
{
b[j]=0;
}
}
}
}

for (int i=0;i<x;i++)
{
cout<<a[i]<< "";
}
cout <<endl;

for (int i=0;i<y;i++)
{
cout<<b[i]<< "";
}
return 0;
}




adventurelw 2009-03-04
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 ppass 的回复:]
更正一下:
步骤3. 遍历一遍数组A,将array[a[i]]的值=1; //不是++,因为A中可能也有重复的.
步骤5: 将>1的值统统删除. //不是=2,因为B中有重复的,值-1,就是重复的次数.
[/Quote]
这个赞!学习了
虽然跟题目有些不一样,题目还要判断A、B中哪个交集元素的个数较少;但是思路很值得学习!
顺着这个思路,是不是可以多建一个array[nmax],按照同样的办法遍历B、A,然后比较两个数组中大于1的元素的大小,就可以确定是删除A中的还是B中的了。只是这样复杂度增了nA+nB。
八级程序员 2009-03-04
  • 打赏
  • 举报
回复
[Quote]{0}[/Quote]
给出我很菜的想法:
1,判断两个数组的大小
2,求出交集
3,用交集去判断源数组中元素少的一个,然后把相关元素删掉!
4,至于楼楼上的所有程序俺都看不懂啊~ 哈哈

#include <iostream>
using namespace std;
class strout
{
public:
strout(string s1)
{
cout <<s1<<endl;
}
};
int main()
{
string s = "发布代码请使用代码插入工具!\n 谢谢!";
strout so(s);
return 0;
}
xuhb95083023 2009-03-04
  • 打赏
  • 举报
回复
排序以后,线性复杂度的实现


#include <iostream>
#include <stddef.h>
#include <stdlib.h>
#include <string>
#include <iterator>
#include <algorithm>
#include <vector>

using namespace std;

template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
OutputIterator delete_intersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, OutputIterator dest)
{
int count = 0;
while (first1 != last1 && first2 != last2) {
if (*first1 > *first2) {
*dest = *first2;
++first2;
++dest;
} else if (*first1 < *first2) {
*dest = *first1;
++first1;
++dest;
} else {
++first1;
++first2;
}
}

for (;first1 != last1; ++first1) *dest = *first1;
for (;first2 != last2; ++first2) *dest = *first2;

return dest;
}

int main() {
int a[] = {1,1,2,2,5,6,9,9};
int b[] = {1,2,3,4,4,6,7,8,9,9,9,10};

vector<int> vc;

delete_intersection(a, a + sizeof(a)/sizeof(a[0]), b, b + sizeof(b)/sizeof(b[0]), back_inserter(vc));

std::copy(a, a + sizeof(a)/sizeof(a[0]), ostream_iterator<int>(cout, ",")); cout << endl;
std::copy(b, b + sizeof(b)/sizeof(b[0]), ostream_iterator<int>(cout, ",")); cout << endl;
std::copy(vc.begin(), vc.end(), ostream_iterator<int>(cout, ",")); cout << endl;

::system("PAUSE");
return EXIT_SUCCESS;

}
ppass 2009-03-04
  • 打赏
  • 举报
回复
更正一下:
步骤3. 遍历一遍数组A,将array[a[i]]的值=1; //不是++,因为A中可能也有重复的.
步骤5: 将>1的值统统删除. //不是=2,因为B中有重复的,值-1,就是重复的次数.
ppass 2009-03-04
  • 打赏
  • 举报
回复
我的只是个思路,实现起来,具体的还需要在效率方面细化.

这个算法不是一时半会想出来的,我以前做POI兴趣点搜索,动辄70万的点.
判断条件有很多,按名称,按区号,按类别等等,这时就需要起码3个结果集的交集.

我想了一个多月,加上改进,总共3个月实现70万条记录在ARM 133Mhz下非常短的时间得到交集..
理论上不会有比这更快的方法了.
xuhb95083023 2009-03-04
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 arong1234 的回复:]
这种东西本来就考算法,你再用系统提供的函数规避,嘿嘿,不想过关了

引用 3 楼 xuhb95083023 的回复:
我想应该先排序,另外可以参考标准库std::set_intersection的实现
[/Quote]

因此我说参考标准库std::set_intersection的实现,没说拿过来用,其实熟读标准库那一坨常用算法,很多问题自然迎刃而解,
adventurelw 2009-03-04
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 adventurelw 的回复:]
引用 10 楼 ppass 的回复:
我给出一个另类的思路,内存开销可能会大,但速度绝对快.
1. 找出2个数组的最大值nMax.
2. 定义一个桶array,容量为nMax.并全部初始化为0.
3. 遍历一遍数组A,将array[a[i]]的值++;
4. 遍历一遍数组B,将array[b[i]]的值++;
5. 遍历一遍数组array,将值为2的值找出来,在B中删除,即可.

老大,你确定你这个算法可以?
a[10] = {1, 2, 4, 5, 3, 6, 5, 6, 3, 5};
b[16] = {2, 5, 6, 7, 8, 4, 3, 5, 6, 7…
[/Quote]
不好意思,又想了一下,发现这个算法还是可以,就是遍历A的时候,array[a[i]]不能大于1;遍历B的时候,不能大于2;需要设置判断条件。
但还是需要判断交集元素在那个数组中多……
adventurelw 2009-03-04
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 ppass 的回复:]
我给出一个另类的思路,内存开销可能会大,但速度绝对快.
1. 找出2个数组的最大值nMax.
2. 定义一个桶array,容量为nMax.并全部初始化为0.
3. 遍历一遍数组A,将array[a[i]]的值++;
4. 遍历一遍数组B,将array[b[i]]的值++;
5. 遍历一遍数组array,将值为2的值找出来,在B中删除,即可.
[/Quote]
老大,你确定你这个算法可以?
a[10] = {1, 2, 4, 5, 3, 6, 5, 6, 3, 5};
b[16] = {2, 5, 6, 7, 8, 4, 3, 5, 6, 7, 2, 1, 5, 9, 12, 10};

那么该是array[12] = {0};
遍历a之后,array[5] = 3;再遍历b,array[5] = 6
但算法中根本没考虑到这一点。
遍历两个数组之后,只有array中元素值为0或1的确定不是交集元素,其余的都可能是交集元素,该怎么考虑?
还是觉得楼主的算法是可以执行的。
zclever 2009-03-04
  • 打赏
  • 举报
回复
[Quote=引用楼主 matrix2009 的帖子:]
如题,删除两个整型数组A和B的交集,要求是,假如A数组有3个1,B数组有2个1,则删除B数组的两个1.
要注意代码的质量。
我当时笔试时考虑的不全面,程序有bug.
我想知道大家会怎么做。尤其是两个数组大小不一时怎么办
我当时的想法是先排序,然后遍历两个数组,找到相同元素,比较相同元素的个数,将个数少的删除之。
大家怎么作呢?
[/Quote]
为什么将个数少的删除?个数指的是元素的个数还是重复元素的个数?题目有点疑惑啊
jakqigle 2009-03-04
  • 打赏
  • 举报
回复
如果不用STL的话,没想到比楼上们所说的跟更好的办法
ppass 2009-03-04
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 fallening 的回复:]
引用 10 楼 ppass 的回复:
我给出一个另类的思路,内存开销可能会大,但速度绝对快.
1. 找出2个数组的最大值nMax.
2. 定义一个桶array,容量为nMax.并全部初始化为0.
3. 遍历一遍数组A,将array[a[i]]的值++;
4. 遍历一遍数组B,将array[b[i]]的值++;
5. 遍历一遍数组array,将值为2的值找出来,在B中删除,即可.

如果A中不含有S,B中含有两个S?
[/Quote]

这个倒好解决. 那就首先A,B互换一下,
然后还是删除B.只要在步骤5中找到值为2的,就遍历B找到重复的删除.
效率的话可以先在步骤4,5之间把B排序.

bfhtian 2009-03-04
  • 打赏
  • 举报
回复
[Quote=引用楼主 matrix2009 的帖子:]
如题,删除两个整型数组A和B的交集,要求是,假如A数组有3个1,B数组有2个1,则删除B数组的两个1.
要注意代码的质量。
我当时笔试时考虑的不全面,程序有bug.
我想知道大家会怎么做。尤其是两个数组大小不一时怎么办
我当时的想法是先排序,然后遍历两个数组,找到相同元素,比较相同元素的个数,将个数少的删除之。
大家怎么作呢?
[/Quote]
没想出更好的算法
arong1234 2009-03-04
  • 打赏
  • 举报
回复
这种东西本来就考算法,你再用系统提供的函数规避,嘿嘿,不想过关了

[Quote=引用 3 楼 xuhb95083023 的回复:]
我想应该先排序,另外可以参考标准库std::set_intersection的实现
[/Quote]
adventurelw 2009-03-04
  • 打赏
  • 举报
回复
10楼老大能否再详细一些,我新手,看不太明白
因为可能有a[i] = a[j] = b[k] = b[m] = b[l]的情况,即遍历后除去容器中元素数值为0或者1的下标,都是交集元素的可能(还有情况就是某个数组中含有多个某个值),好像没法判断啊。。。。。。
并且题目说的大概是删除含有交集元素较少的一个数组中的元素。。。。。。
加载更多回复(14)

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧