急求一个算法 :) ( 积分: 100 )

  • 主题发起人 主题发起人 雪狐狸
  • 开始时间 开始时间

雪狐狸

Unregistered / Unconfirmed
GUEST, unregistred user!
有10个数组,每个数组为500个数。
这500个数是从000到999之间随机产生的。
求:这10个数组中相同的数字。
请提示一下算法。谢谢!
注:要储存。
 
提供个思路,先把每个数组里相同的数删除只剩一个,然后把10个数组的数读到一个大数组里,再排序,0-999如果有连续10个相同数,则在每个数组中都有这个数。
 
To nicai_wgl:
求的就是相同的数字。呵呵,继续。
 
将10个数组中所有的数字都放到一个List中(在此过程中进行重复情况计数),然后,删
除该List中出现次数少于10次的数字(每个数组都有的数字,出现次数不会小于10次)。
对这个剩下来的“精英”List进行遍历,循环检查它们出现在每个数组中的情况(为了提
速,可以将数组转化成已排序的List,以便进行二分法定位),如果都出现,就输出。
 
声明一个数组A[0..999],遍历10个数组所有数据,每个数字出现一次就在数组A上索引和它相等的那个元素里+1,最后输出数组A中等于10的元素的索引

修改下,忽略个问题,同个数组中会出现相同数字的,所以遍历前先整理10个数组,相同数字都只保留1个.
 
提供思路:
1 首先把每个数组里重复的数字算成一个值 如 (1,2,2)变成(1,2)
2 用tlist把所有数组的数字add进去
3 找出该list链表中出现次数当且仅当为10的那些数字,把这些数字add到
另 一个list中去
注: 这另一个list链表中的存储的数就是你要的数
 
我给你提供一个思路
1,10个数组分成5组,每组之间比较出相同的,组成新的5个数组
2,新的5个数组分成3组,每组之间比较出相同的,组成新的1个数组,单独的第三组只有1个数组不参与比较
3,最后2个数组进行比较。

时间分析:最极端的情况
比对次数25万*8=2000000,200万次比较加负值,P42.8的机器时间应该不会超过0.3秒
 
结合Hydra0的思路,程序如下:
TMyArray: array[0..499] of Integer;
TResult = record
Count: Integer;
ArrayID: Integer;
end;
TResultArray: array[0..999] of TResult;

var
Z: array[1..10] of TMyArray;
R: TResultArray;
i, j: Integer;
begin
FillChar(R, SizeOf(R), 0);
for i := 1 to 10 do
for j := 0 to 499 do
begin
if R[Z[j]].ArrayID < i then { 每个数组相同数最多计数一次 }
begin
Inc(R[Z[j]].Count);
R[Z[j]].ArrayID := i;
end;
end;
for i := 0 to 999 do
if R.Count = 10 then
Memo1.Lines.Add(IntToStr(i));
end;
 
nicai_wgl
我粗略的想法很不完善的,不过你的程序应该效率比较高吧,总共只有6000次循环和比较,并且没有花费时间预先处理原始数据
 
如果这样处理会怎样:
声明一个二维数组A[0..10,0..999]
例如:在第1组有258这个数,则A[1,258]的值为“1”,否则为“0”
设一个循环,如果A[i,258]的所有值相加等于10,则“258”这个数在10个数组中都有。
这样循环1000次就够了。
可否?
还有,怎样保存和读入这10个数组呢?
 
var
fs: TFileStream;
array1,array2,array3,array4,array5,array6,array7,array8,array9,array10:array[0..499] of Longword;
begin
//保存
try
fs:= TFileStream.Create('arrays.dat',fmOpenWrite);
fs.Write(array1,SizeOf(array1));
fs.Write(array2,SizeOf(array2));
fs.Write(array3,SizeOf(array3));
fs.Write(array4,SizeOf(array4));
fs.Write(array5,SizeOf(array5));
fs.Write(array6,SizeOf(array6));
fs.Write(array7,SizeOf(array7));
fs.Write(array8,SizeOf(array8));
fs.Write(array9,SizeOf(array9));
fs.Write(array10,SizeOf(array10));
finally
FreeAndNil(fs);
end;
//读取
try
fs:= TFileStream.Create('arrays.dat',fmOpenRead);
fs.Read(array1,SizeOf(array1));
fs.Read(array2,SizeOf(array2));
fs.Read(array3,SizeOf(array3));
fs.Read(array4,SizeOf(array4));
fs.Read(array5,SizeOf(array5));
fs.Read(array6,SizeOf(array6));
fs.Read(array7,SizeOf(array7));
fs.Read(array8,SizeOf(array8));
fs.Read(array9,SizeOf(array9));
fs.Read(array10,SizeOf(array10));
finally
FreeAndNil(fs);
end;
end;
 
nicai_wgl说的对,
先把每个数组里相同的数删除只剩一个,然后把10个数组的数读到一个大数组里,
数据中每个元素有两个值,一个是数组下标,一个是值,然后根据元素的值排序,
最后用KMP配匹10个000到10个999或者从头匹配十个连在一起的数。
 
假如用到nicai_wgl的数组定义方法,那代码还要少
Z怎么来的,去看前面nicai_wgl的程序
var
fs: TFileStream;
begin
//保存
try
fs:= TFileStream.Create('arrays.dat',fmOpenWrite);
fs.Write(Z,SizeOf(Z));
finally
FreeAndNil(fs);
end;
//读取
try
fs:= TFileStream.Create('arrays.dat',fmOpenRead);
fs.Read(Z,SizeOf(Z));
finally
FreeAndNil(fs);
end;
end;
 
呵呵,回头看看还是有问题,程序修改了一下。
 
谢谢大家。
原来我打算用表来解决这个问题
现在看来,应该用大家说的“数组”来解决。
原谅我基础学得不好
可我还是想用我上面说的二维数组来解决算法的问题,因为毕竟只有1000个循环。
(谢谢大家数组的提示)
存储还得谢谢“Hydra0”,
我才刚开始学习“流”这个东西
真想不到还能用到这里,谢谢
最后,真的很感谢所有给我提示的朋友
谢谢!!!
 
多人接受答案了。
 
后退
顶部