请教一个算法问题,有两个数组A,B,判断A中是否至少有一个元素和B中元素相同

问题描述

最笨的办法当然是二层嵌套循环,但觉得应该有更好的方法,但是着实想不出来,想听听大家的意见,大家帮帮小弟i.estring[]A={"X","Y","Z","W"};string[]B={"X","E","Z","U","V"};只要发现B中有一个A的元素就可以

解决方案

解决方案二:
数据量不大(100条内100*100=10000次还是很快的),这个方法简单实用如果数量大,可以考虑排序后采用对分查询等
解决方案三:
什么是对分查询能不有说一下
解决方案四:
对分查找就是携手折半查找,也叫二分查找
解决方案五:
就是折半查找,也叫二分查找
解决方案六:
usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Text;usingSystem.Windows.Forms;namespaceWindowsApplication6{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}string[]A={"X","Y","Z","W"};string[]B={"X","E","Z","U","V"};privatevoidbutton1_Click(objectsender,EventArgse){Dictionary<string,object>Test=newDictionary<string,object>();foreach(stringainA){if(!Test.ContainsKey(a)){Test.Add(A,null);}}boolReturn=false;foreach(stringbinB){if(Test.ContainsKey(b)){MessageBox.Show("发现重复项:"+b);Return=true;break;}}if(!Return){MessageBox.Show("没有发现重复项"+b);}}}}

我认为最快,最稳定的算法...O(n)n=A.len+b.len
解决方案七:
usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Text;usingSystem.Windows.Forms;namespaceWindowsApplication6{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}string[]A={"X","Y","Z","W"};string[]B={"X","E","Z","U","V"};privatevoidbutton1_Click(objectsender,EventArgse){Dictionary<string,object>Test=newDictionary<string,object>();foreach(stringainA){if(!Test.ContainsKey(a)){Test.Add(a,null);}}boolReturn=false;foreach(stringbinB){if(Test.ContainsKey(b)){MessageBox.Show("发现重复项:"+b);Return=true;break;}}if(!Return){MessageBox.Show("没有发现重复项");}}}}

上楼的代码有点问题...欢迎拍砖
解决方案八:
Re:楼主  你的直觉告诉你应该有更好的方法,确实如此!  我们思考一下:  假设不是计算机来比较,而是人脑来比较,那么人脑会怎么思考呢?人脑首先会找各种窍门来排除不可能的元素,缩小查找范围吧!怎样让程序有接近人脑一样的思路,那就要靠咱们程序员的智慧了。我举例说明一下我要介绍的这种模拟人脑的思路,即模糊比较法:假设本例中B组出现了非字母元素,例如中文字或者数字,即:string[]A={"X","Y","Z","W"};string[]B={"X","我","9","E","Z","U","V"};我们人类一看就知道,A组的特征就是纯字母,B组的特征就是混合有非字母的元素,那我们大脑就会想,根本不用考虑这些非字母的元素,很自然的将其排除在视线之外。根据人脑的这种思路编出的程序会是:第一遍先通过快速的模糊比较,剔除不可能的元素。第二遍再用楼主所说的二层嵌套循环,进行精确比较。这就是楼主苦求的更好的方法。这种方法在元素数量多的时候,效果尤其明显。我猜GOOGLE和BAIDU的搜索引擎也会这么做吧,如果不是,那他们大概需要升级了。模糊比较怎么做呢?首先,模糊比较的方法可以不止一种,也就是说可以有多道工序按顺序叠加在一起,只要条件合理都可以写上。假如楼主知道A、B来源都是纯字母,那就不必做上述的剔除非字母元素的程序,做了反而耽误时间。假如楼主知道A组字符串长度范围,就可以把B组超长超短的字符串剔除。还有种情况,假如楼主知道A、B组本身会出现大量重复的元素,就可以先做个剔除本组中重复元素的操作,这会为最后的二层嵌套循环节省时间。如果元素数量很大的话,建议先做个排序再做剔除本组重复元素,这样剔除起来比较快,排序后的数组也会为最后的二层嵌套循环节省时间,甚至可以实现速度更快的二分法(好像也叫二叉树)。以上方法只是假设,在本例中并不适用,不过通过思考这些方法大家应该对模糊比较有个初步的认识了。我这里提一个比较晦涩难懂的模糊比较法,抽取基因法,这在本例中是最有效的,我尽量说的详细点。这个方法中,元素都设定为char型变量,A组字母先用位操作计算出一个结果,即找出A组字母的基因,然后遍历一遍B组元素,把不含此基因的元素剔除掉。使用基因的方法有两种,&和|,我这里先详细介绍&方法,稍后会给出完整程序:先把A组所有字母按位进行&计算,即:charresult='X'&'Y'&'Z'&'W';我们都知道字母的ASCII范围:'A'=65=01000001'Z'=90=01011010所以我们把A组所有元素按位&后结果存入result,观察result的后5位(前面的010是不会变的),看是否有1出现,如果后5位都是0,即result=01000000=64,那我们就跳过这种模糊比较方案。如果某位是1,例如本例:'X'=01011000'Y'=01011001'Z'=01011010'W'=01010111result=01010000就证明A组所有元素在该位都是1,我们就暂且称这个result为A组元素的基因。用这个基因与B组元素挨个&一次,如果结果与原先结果一致,就证明B组这个元素也包含相同的基因,我们保留,如果结果不一致,就剔除这个元素,因为这个元素某位是0,而A组所有元素该位都是1。第二种抽取基因的方法大家都已经想出来了吧,那就是用按位|的方法做,后边我不罗嗦了,给出程序大家讨论一下吧!usingSystem;namespaceConsoleApplication9{classProgram{staticvoidMain(string[]args){char[]A={'X','Y','Z','W'};char[]B={'X','E','Z','U','V'};//用&方法算出基因,本例中会剔除B[]中的'E'charresult=(char)0xffff;intpoint=0;foreach(charainA)result&=a;if(result!=64)foreach(charbinB)if((b&result)==result)B[point++]=b;//用|方法算出基因,本例中该基因不可用,跳过剔除foreach(charainA)result|=a;if(result!=95){intcount=point;point=0;for(inti=0;i<count;i++)if((B[i]&result)==result)B[point++]=B[i];}//最后的嵌套循环for(inti=0;i<point;i++)foreach(charainA)if(B[i]==a){Console.WriteLine("Findout'{0}'inB!",a);i=point;break;}Console.Read();}}}

  有人会问用|方法前result为什么不初始化成0,因为本例中不初始化不会出错,所以偷懒没写了。还有判断条件常数64和95给的太直接了吧,换一道题就不适用了。这确实是个问题,那完整的判断语句写法是什么呢?  楼下说吧!
解决方案:
刚才没仔细看有些错误,我改正:usingSystem;namespaceConsoleApplication9{classProgram{staticvoidMain(string[]args){char[]A={'X','Y','Z','W'};char[]B={'X','E','Z','U','V'};intpoint=B.Length;//用&方法算出基因,本例中会剔除B[]中的'E'charresult=(char)0xffff;foreach(charainA)result&=a;if(result!=(result&~0x1f)){point=0;foreach(charbinB)if((b&result)==result)B[point++]=b;}//用|方法算出基因,该基因不可用,跳过剔除//这里省略了result=0;foreach(charainA)result|=a;if(result!=(result|0x1f))for(inti=0;i<point;i++)if((B[i]|result)!=result)B[i--]=B[--point];//最后的嵌套循环for(inti=0;i<point;i++)foreach(charainA)if(B[i]==a){Console.WriteLine("Findout'{0}'inB!",a);i=point;break;}Console.Read();}}}

解决方案:
我先慢慢消化一下,再来结贴

时间: 2024-10-07 19:11:34

请教一个算法问题,有两个数组A,B,判断A中是否至少有一个元素和B中元素相同的相关文章

java编写一个算法,一个数用数组表示,执行加1操作,之后的数组用一个数表示。

问题描述 java编写一个算法,一个数用数组表示,执行加1操作,之后的数组用一个数表示. 用java编写一个算法,一个数用数组表示,执行加1操作,之后的数组用一个数表示. 解决方案 数组可以表示很多数的-你说,用一个数表示啥意思?? 解决方案二: 你应该是想要下面的实现.如果有用请采纳. import java.util.ArrayList; import java.util.List; public class TestMain { public static void main(String

[算法问题]交换两个子数组的元素值

问题描述: 设a[0:n-1]是一个有n个元素的数组,k(0<=k<=n-1)是一个非负整数.试设计一个算法将子数组 a[0:k]与a[k+1:n-1]换位.要求算法在最坏情况下耗时O(n), 且只用到O(1)的辅助空间. 这个问题比较常见了,一般的办法就是分别把两个子数组分别逆序排列,然后对整个数组进行逆序排列.也就是说,对一个数组 a[8] = {1,2,3,4,5}而言,如果k = 2,那么首先对两个子数组进行逆序操作得序列{3, 2,1,5,4},然后对整个数组逆序排列得到{4,5,1

50分,在线求一个算法问题,有两个数组A,B,判断A中是否至少有一个元素和B中元素相同(即判断两个数组的元素是否有交集)

问题描述 最笨的办法当然是二层嵌套循环,但觉得应该有更好的方法,但是着实想不出来,想听听大家的意见,大家帮帮小弟i.estring[]A={"X","Y","Z","W"};string[]B={"X","E","Z","U","V"};只要发现B中有一个A的元素就可以 解决方案 解决方案二:循环应该比较简单如果实在数据量大,可

求一个合理算法,比较两个数据量较大的集合

问题描述 求一个合理算法,比较两个数据量较大的集合 现有listA,数据库B,A中的数据如果与B中不同(包含不存在的情况), 则将不同或不存在的数据记录到B中, 现在问题是,listA和数据库B都有大量数据, 求一个合理的比较二者数据的算法 解决方案 先排序再比较啊. 比较的时候: 如果 A[i] == B[j],继续下一个比较 A[i+1] 和 B[j+1]: 如果 A[i]<B[j].或者B没有可以比较的数,就是不存在: 如果 A[i]>B[j],继续下一个比较 A[i] 和 B[j+1]

link中如何交替混编两个数组,并且保持两个数组的装填比率一样,内容则是随机的?

问题描述 link中如何交替混编两个数组,并且保持两个数组的装填比率一样,内容则是随机的? link中如何交替混编两个数组,并且保持两个数组的装填比率一样,内容则是随机的? 解决方案 内容随机我说了,用OrderBy按照Guid随机排序.然后要想比率一样,可以产生一个0~1的随机数,如果<0.5就是第一个,否则是第二个.

link中调用一个方法,出现两个括号是什么意思?比如LoadEvent()();这个有什么用?

问题描述 link中调用一个方法,出现两个括号是什么意思?比如LoadEvent()();这个有什么用? link中调用一个方法,出现两个括号是什么意思?比如LoadEvent()();这个有什么用? 解决方案 有没有更进一步的代码,看下LoadEvent()返回的是什么类型,是不是返回的是一个委托?如果是委托,可以继续调用.

[算法问题]合并两个已经排序的数组为另一个数组

问题描述: 设子数组a[0:k]和a[k+1:n-1]已排好序(0<=k<=n-1).试设计一个合并这两个子数组为排好序的数组a[0:n-1]的算法.要求算法在最坏的情况下所用的计算时间为O(n), 且只用到O(1)的辅助空间. 这一题比较简单,看代码就知道了. #include <stdio.h> void DisplayArray(int *pArray, int nLen) { for (int i = 0; i < nLen; ++i) { printf("

请教一个算法问题时间复杂度要求是(1)

问题描述 请教一个算法问题时间复杂度要求是(1) 做项目的时候有一个处理大致是这样的:需要每次插入map;每次输入是(1,0),(2,0),(3,0):(2,1),(3,1)...当key是新添加的或者key对应的count大于前一次就要把这个key拿出来,时间复杂度要求是O(1), 请教大家有没有好的方法 解决方案 不可能事件复杂度是1,最低是LogN,不过这个很接近1了.除非你有无限制的内存,然后直接地址映射. 解决方案二: 一个数组中只有0,1,2三个元素,进行排序,要求时间复杂度为O(n

c语言-请教各位大神,实现用数组表示大整数及大整数与字符串相互转化的两个函数

问题描述 请教各位大神,实现用数组表示大整数及大整数与字符串相互转化的两个函数 怎么用数组表示大整数呢,大整数到底有多大,大整数怎么转化成字符串,c语言没有学好,对这些完全不懂啊 解决方案 字符数组实现两个大整数的加法用字符串表示大整数 解决方案二: 用char数组存大整数,比如你要存4564646874646465464646878797979871465465465,明显超过了long long的范围 那么此时就用数组存储了, char num[1000] = {0}; //声明一个数组,可