如何取两个已排序数组的交集?

programbin 2007-09-20 11:16:16
例:
1,3,5,6,7,9
2,4,6,7,8,9
如何能够最快的取出交集.
有没有什么好的算法.我不想去一个一个的循环比较.
...全文
1772 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
云中Tony 2012-02-21
  • 打赏
  • 举报
回复
int bIndex=0;
int num = 0;
int[] iaArray = {1,3,5,6,7,9};
int[] ibArray = {2,4,6,7,8,9};
List<Integer> newList = new ArrayList<Integer>();
A:for(Integer a : iaArray){
B:for(int i=bIndex;i<ibArray.length;i++){
num++;
if(a > ibArray[i]){
bIndex = i +1;
continue B;
}
if(a = ibArray[i]){
newList.add(a);
continue A;
}
if(a < ibArray[i]){
continue A;
}

}
}

循环11次
cshnet7 2008-06-04
  • 打赏
  • 举报
回复
mark
宋玮-深圳 2007-09-27
  • 打赏
  • 举报
回复
遍历一个小的数组,因为有序,复杂度能够做到O(min(n,m))
daniel_kaka 2007-09-27
  • 打赏
  • 举报
回复
执行循环次数:36次
daniel_kaka 2007-09-27
  • 打赏
  • 举报
回复
//用模式匹配的算法~
public static void getPattern(Object[] strA, Object[] strB) {
// 只要有一个null,就返回null
if (strA == null || strB == null || strA.length == 0
|| strB.length == 0) {
System.out.println("");
return;
}
int lengthA = strA.length;
int lengthB = strB.length;
Object[] longStr = lengthA > lengthB ? strA : strB;
Object[] shortStr = lengthA > lengthB ? strB : strA;
Map<Integer, List<Object[]>> maxSubstrList = new TreeMap<Integer, List<Object[]>>();
for (int length = shortStr.length; length >= 0; length--) {
for (int startIndex = 0; startIndex <= shortStr.length - length; startIndex++) {
Object[] tmpO = new Object[length];
System.arraycopy(shortStr, startIndex, tmpO, 0, length);

String _tmp1 = Arrays.toString(longStr).replaceAll("\\[", "").replaceAll("\\]", "");
String _tmp2 = Arrays.toString(tmpO).replaceAll("\\[", "").replaceAll("\\]", "");
if ((_tmp1.indexOf(_tmp2) > -1) && (Arrays.asList(longStr).containsAll(Arrays.asList(tmpO)))) {
int len = tmpO.length;
List<Object[]> list;
if (maxSubstrList.containsKey(len)) {
list = (List<Object[]>) maxSubstrList.get(len);
} else {
list = new ArrayList<Object[]>();
}
if (!list.contains(tmpO)) {
list.add(tmpO);
}
maxSubstrList.put(len, list);
}
}
}
//找到所有匹配子串
if (maxSubstrList.size() == 0) {
return;
} else {
Iterator<Entry<Integer, List<Object[]>>> it = maxSubstrList
.entrySet().iterator();
Entry<Integer, List<Object[]>> entry = it.next();
while (it.hasNext()) {
entry = it.next();
List<Object[]> maxList = entry.getValue();
for (Object[] str : maxList) {
System.out.println(Arrays.toString(str));
}
}
}
}

测试:getPattern(new Integer[]{1,2,4,6,7,8,9},new Integer[]{1,3,4,7,8,9,11,22});
结果:
[1]
[4]
[7]
[8]
[9]
[7, 8]
[8, 9]
[7, 8, 9]
daniel_kaka 2007-09-27
  • 打赏
  • 举报
回复
在串中有个算法佳模式匹配~~
这个可以看作一个特殊的模式匹配算法~~
效率绝对高~~

ddystar6045 2007-09-27
  • 打赏
  • 举报
回复
list.retainAll 好像效率不是最高的

用归并, m+n的复杂度

list1 size m
list2 size n
超级大笨狼 2007-09-25
  • 打赏
  • 举报
回复
查找范围是:
两个数组中最大的下限和最小的上限,先判断下这个再做循环二分查找.
超级大笨狼 2007-09-25
  • 打赏
  • 举报
回复
排序过了,为什么不用二分查找?
笑羽酣天 2007-09-24
  • 打赏
  • 举报
回复
因为是排好序了,可以同时搜索
int[] a = {1,3,5,6,7,9};
int[] b = {2,4,6,7,8,9};
Set s = new HashSet();
for (int i=0, j=0; i<a.length && j<b.length; ) {
if (a[i]==b[j]) {
s.add(""+a[i]);
i++;
j++;
} else if (a[i] > b[j]){
j++;
} else {
i++;
}
}
if (s.size()==0) {
Sytem.out.println("no intersection");
} else {
System.out.println(Arrays.toString(s.toArrays()));
}
rightyeah 2007-09-24
  • 打赏
  • 举报
回复
btw,为什么不用循环,循环是最基本的控制结构之一,有什么不好?lz怎么不说不用判断……
rightyeah 2007-09-24
  • 打赏
  • 举报
回复
晕,不过是个线性复杂度的问题,至于闹这么大嘛
manbaum 2007-09-22
  • 打赏
  • 举报
回复
楼主的贴子到处贴啊?C++论坛里也贴这个。已经讨论过了,不可能不用循环比较。只不过是看你怎么优化循环了。
ukeychen 2007-09-22
  • 打赏
  • 举报
回复
public class t{
private int[] a={0,1,3,3,5,7,9};//去比较
private int[] b={-1,0,2,3,4,5,9,9,10};//被比较
private int[] c=null;
public t(){
c=jiaoJi(a,b);
print(); //打印
}

public int[] jiaoJi(int[] a,int[] b){ //处理交集函数
//确定 中间变量数组 jj 的数组大小,其大小为,a,b两数组较小的数组大小
int size;
if (a.length>b.length){
size=b.length;
}else{
size=a.length;
}
//建立中间变量数组 jj
int [] jj=new int [size];
for (int i=0;i<size;i++){ //赋值
jj[i]=0;
}
int k=0;//记录交集元素插入到jj数组的位置
int e=0;//记录 下一次比较的开始位置
for (int i=0;i<a.length;i++){
for (int j=e;j<b.length;j++){
if (a[i]==b[j]){
jj[k++]=a[i]; //存储交集元素,数组jj 下标 k 加一
e=j+1; //记录 下一次比较的开始位置,既从j后面的元素开始
break;//跳出for循环
}
}
}

int [] zzjj=new int[k]; //根据K建立交集的是数组zzjj
for (int i=0;i<k;i++){
zzjj[i]=jj[i];
}
return zzjj;
}

public void print(){//打印
for(int i=0;i<c.length;i++){
System.out.print(c[i]+", ");
}
System.out.println();
}

public static void main(String args[]){
new t();
}

}

我这个也行的,测试通过
李世佳 2007-09-22
  • 打赏
  • 举报
回复
可以用set吗?要是可以拿就简单了.
zephyr_cc 2007-09-22
  • 打赏
  • 举报
回复
楼主的问题本身就是矛盾的,所以...
manbaum 2007-09-22
  • 打赏
  • 举报
回复
都写的这么复杂干吗,java里提供了Set类,直接就可以算交集。
silence1214 2007-09-22
  • 打赏
  • 举报
回复
往hashtable里面插入啊,遇到存在的就是交集的一个数据项
LostKingGK 2007-09-22
  • 打赏
  • 举报
回复
//C++版本
template<class Type>
void union_intersect(vector<Type>& l,vector<Type>& r,vector<Type>& out)
{
sort(l.begin(),l.end());
sort(r.begin(),r.end());
out.clear();
vector<Type>::iterator IL=l.begin();
vector<Type>::iterator IR=r.begin();
while(IL!=l.end()&&IR!=r.end())
{
if(*IL<*IR)
{
while(IL!=l.end()&&*IL<*IR)
++IL;
}
else if(*IR<*IL)
{
while(IR!=r.end()&&*IR<*IL)
++IR;
}
else
{
out.push_back(*IL);
++IL; ++IR;
}
}
}
sniperhuangwei 2007-09-21
  • 打赏
  • 举报
回复
1,3,5,6,7,9
2,4,6,7,8,9

用两个整型,第一位代表0,第二位1,以此类推.

如果上面两组数对应整数应该是:
0101011101........
0010101111........
将这两数进行&操作不就得到交集了.


如果整数集合太大就自己做位域吧.
加载更多回复(19)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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