• 主页
  • ASP
  • .NET Framework
  • Web Services
  • VB
  • VC
  • 图表区
  • 分析与设计
  • 组件/控件开发
  • LINQ

数组比较算法

huing 2009-11-19 04:44:42
原来有个送分帖子,单没有人回答哈
http://topic.csdn.net/u/20091119/15/ff77ed42-dcf8-4fff-8e53-f8e6b30fe40a.html

题目:怎么快速找出2个数组中的相同项,数组可能很大
...全文
139 点赞 收藏 21
写回复
21 条回复
hhxx_cj 2009年11月19日
用循环,我觉得最快了,再就IndexOf就行了,这样多点也应该没问题吧

挺好的
回复 点赞
阿非 2009年11月19日
[Quote=引用 15 楼 huing 的回复:]
哈,现在理解了,这个是用空间来换时间的
[/Quote]

他特意说 元素很多 就是想问你 怎么找到折中的方案 ~

都不用说 具体的实现

只要说出关键的部分就行了~

就是想考你排序的的复杂度 和 如何提高排序效率
回复 点赞
我姓区不姓区 2009年11月19日
第三个方法改改:

static List<int> GetSameItem3(int[] arrA, int[] arrB)
{
Dictionary<int, bool> dic = new Dictionary<int, bool>();
List<int> list = new List<int>();
foreach (int i in arrA)
{
if (!dic.ContainsKey(i))
dic.Add(i, false);
}
foreach (int i in arrB)
{
if (dic.ContainsKey(i))
{
dic[i] = true;
list.Add(i);
}
else
dic.Add(i, false);
}
return list;
}
回复 点赞
我姓区不姓区 2009年11月19日
提供四种方法,第四种是C#3.0以上才有的linq

static void Main(string[] args)
{
int[] arrA = new int[short.MaxValue];
int[] arrB = new int[short.MaxValue];
Random r = new Random(Environment.TickCount);
for (int i = 0; i < short.MaxValue; i++)
{
arrA[i] = r.Next(0, int.MaxValue);
arrB[i] = r.Next(0, int.MaxValue);
}
//以上是构建数据
int tick = Environment.TickCount;
GetSameItem1(arrA, arrB);
Console.WriteLine(Environment.TickCount - tick);
tick = Environment.TickCount;
GetSameItem2(arrA, arrB);
Console.WriteLine(Environment.TickCount - tick);
tick = Environment.TickCount;
GetSameItem3(arrA, arrB);
Console.WriteLine(Environment.TickCount - tick);
tick = Environment.TickCount;
GetSameItem4(arrA, arrB);
Console.WriteLine(Environment.TickCount - tick);
}

static List<int> GetSameItem1(int[] arrA, int[] arrB)
{
List<int> list = new List<int>();
foreach (int i in arrA)
if (Array.IndexOf(arrB, i) > -1)
list.Add(i);
return list;
}

static List<int> GetSameItem2(int[] arrA, int[] arrB)
{
List<int> list = new List<int>(arrA);
foreach (int i in arrB)
list.Remove(i);
return list;
}

static List<int> GetSameItem3(int[] arrA, int[] arrB)
{
Dictionary<int, bool> dic = new Dictionary<int, bool>();
List<int> list = new List<int>();
foreach (int i in arrA)
{
if (dic.ContainsKey(i))
{
dic[i] = true;
list.Add(i);
}
else
dic.Add(i, false);
}
foreach (int i in arrB)
{
if (dic.ContainsKey(i))
{
dic[i] = true;
list.Add(i);
}
else
dic.Add(i, false);
}
return list;
}

static List<int> GetSameItem4(int[] arrA, int[] arrB)
{
return arrA.Intersect(arrB).ToList();
}

回复 点赞
十八道胡同 2009年11月19日
[Quote=引用 15 楼 huing 的回复:]
哈,现在理解了,这个是用空间来换时间的
[/Quote]
空间换时间是最好的方法,
hashtable应该可以的
回复 点赞
huing 2009年11月19日
明天会把2贴都结了哈
回复 点赞
huing 2009年11月19日
哈,现在理解了,这个是用空间来换时间的
回复 点赞
huing 2009年11月19日
回去测试一下
回复 点赞
lovexilove 2009年11月19日
效率算法 取平衡
回复 点赞
watsonchia 2009年11月19日
[Quote=引用 10 楼 lzsh0622 的回复:]
楼主,你把楼上给你的方法实际测试一下,

凭直觉你是分不清效率高低.
[/Quote]
比较O(n*n)和O(n)的效率,用不着直觉吧。。。
回复 点赞
watsonchia 2009年11月19日
我写那个只是两次线性循环加一次初始化,复杂度是O(n)
回复 点赞
lzsh0622 2009年11月19日
楼主,你把楼上给你的方法实际测试一下,

凭直觉你是分不清效率高低.
回复 点赞
huing 2009年11月19日
[Quote=引用 4 楼 watsonchia 的回复:]
代码实现也不多
C# codeint[] a=newint[10000];int[] b=newint[10000];bool[] flag=newbool[MAX];for (int i=0; i< MAX; i++)
flag[i]=false;for (int i=0; i<10000; i++)
flag[a[i]]=true;for (int i=0; i<10000; i++)if (flag[b[i]])
Console.WriteLine(b[i]);//输出相同元素
[/Quote]

你的这个算法时间是多少?嵌套循环是N*N
回复 点赞
huing 2009年11月19日
[Quote=引用 7 楼 lzsh0622 的回复:]
C# codestring[] arry1=newstring[]{"aa","12","bb" };string[] arry2=newstring[]{"bb","16","ll","ds" };foreach (string strin arry1)
{if (Array.IndexOf(arry2, str)>-1)
{
MessageBox.Show(str.To?-
[/Quote]

这个应该就是嵌套循环了吧?
回复 点赞
lzsh0622 2009年11月19日

string[] arry1 = new string[]{ "aa", "12", "bb" };
string[] arry2 = new string[]{ "bb", "16", "ll", "ds" };

foreach (string str in arry1)
{
if (Array.IndexOf(arry2, str) > -1)
{
MessageBox.Show(str.ToString());
}
}
回复 点赞
huing 2009年11月19日
[Quote=引用 5 楼 mbh0210 的回复:]
引用 1 楼 sandy945 的回复:
将一个数组转换成 字符串

然后判断 另一个数组中的项 是否 在字符串中


这样还不如用哈希表,匹配的时间复杂度为1
[/Quote]
我当时给的答案就是用hashtable。。。。。。
回复 点赞
mbh0210 2009年11月19日
[Quote=引用 1 楼 sandy945 的回复:]
将一个数组转换成 字符串

然后判断 另一个数组中的项 是否 在字符串中
[/Quote]

这样还不如用哈希表,匹配的时间复杂度为1
回复 点赞
watsonchia 2009年11月19日
代码实现也不多

int[] a = new int[10000];
int[] b = new int[10000];
bool[] flag = new bool[MAX];

for (int i = 0; i < MAX; i++)
flag[i] = false;

for (int i = 0; i < 10000; i++)
flag[a[i]] = true;

for (int i = 0; i < 10000; i++)
if (flag[b[i]])
Console.WriteLine(b[i]); //输出相同元素
回复 点赞
watsonchia 2009年11月19日
错了,数据bool[] flag的大小是尽可能大,不是和两上数组相同大小
回复 点赞
watsonchia 2009年11月19日
有空间限制么?没有的话设第三个数组大小一样大的数组bool[] flag,全部初始化false。

设原有数组为int[] a; int[] b;
遍历数组a,赋值flag[a[i]]=true;
遍历数组b,检查如果flag[b[i]]为true,显然数组a中有相同的数。
回复 点赞
发动态
发帖子
.NET技术社区
创建于2007-09-28

4.9w+

社区成员

66.8w+

社区内容

.NET技术交流专区
社区公告
暂无公告