能力值:
( LV2,RANK:10 )
|
-
-
2 楼
楼主能否说下思路,可以参考一下,关注中……还有就是楼主给出的格式每一个都代表一BYTE吗?总过有1G大的数据量?
|
能力值:
( LV9,RANK:370 )
|
-
-
3 楼
如果一个一个的遍历,1G,的确需要很长时间。
用2分法就减少很多啊。
定义一个 数据块大小,比如10000,
在这10000大小的数据块中,用二分法查询,1和2的分界点,平均只需要调用GetPosValue,13次就够了。因为2的13次方差不多就够10000这么大了。
这样快的就非常多了。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
修改你的演算法 盡量多重迴圈就請把它變成
讀取檔案,盡量用binary 0.0。
大部分就是演算法,通常都是優化for迴圈。
或者是不要用遞迴,盡量用迴圈,除非你遞迴的數字不大。
|
能力值:
( LV5,RANK:60 )
|
-
-
5 楼
如果我理解的没错, 数据是按0,1,2,3这样循环出现的,且每次循环不会丢失某一种序列
我的做法:
从黑盒读数据写文件的时候对数据压缩成类似位图的方法
比如100个0,200个1,300个2,200个3,。。。的序列
存储成100,300,600,800,。。。 的类似斐波那契
这样每个位置的数值可以通过二分法对应参数的位置
而存储序列的位置又可以通过取膜对应成真实的数据0,1,2,3。。。
对于压缩度高的应该比较快吧
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
恩,黑盒中的每个位置都是一个byte..
我的方法:(GetPosValue的参数按以下规律来获取黑盒中的数据)
0 //在这里取的是0
20
40
80
160
320
640 //如果在这里发现取的是1,与前面的不一样了,那么就从320到640之间采用二分法来找相邻的位置
另一种方法(也是按以下规律来获取黑盒中数据):
0 //在这里取的是0
1000
2000
3000
4000 //在这里取的是1,与前面不一样了,那么就从3000到4000之间用二分法。
两者速度差不多。
还一种思路,没写出代码,感觉速度也不快。
还是按
20
40
80
160
320
发现在160和320间不一样了,
于是从160这里开始:
160
160 + 20
160 + 40
160 + 80
160 + 160........
速度应该更慢。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
目前是采用的二分法.但我发觉2分的效率还不是蛮高的。
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
黑盒中的数据是不透明的。你想获取某处的数据只有通过调用函数GetPosValue。而且一次只能获取一个byte.
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
等s牛来弄个3秒的,吓死你。
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
学习到新东西了,另外请问谁是S牛啊??
|
能力值:
( LV12,RANK:750 )
|
-
-
12 楼
最极端的情况每个byte都不一样,你怎么搞,这只能一个一个的遍历
否则你没办法确保数据是对的,二分法不能确保数据正确阿,最快的算法就是
一个byte一个byte的遍历
write_to_binary_file(GetPosValue(pos++))
OVER!!!
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
呵呵 学习 了
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
好像蛮有趣的样子,坐等高手的解决思路
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
没有这种最极端的情况.
可以保证0、1、2、3每个byte连续出现的个数至少在20000以上.
二分法的确不能保证数据全部正确,但当出现2W个1后面接几百个2的情况,可以忽略掉这几百个2
用write_to_binary_file(GetPosValue(pos++))的确能保证百分百的精度,但那就不存在算法了啊。而且速度就。。。。
|
能力值:
(RANK: )
|
-
-
16 楼
如果格式是固定的依次由多个0,1,2,3组成, 那么可以用RLE方式压缩, 即{11, 22, 33, 44}, {22,33,44,55}这样, 四个一组, 每个数分别对应0,1,2,3的个数.
查找时直接计算总和就可以了.
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
格式的确是固定的0、1、2、3组成,
但四个元素的个数并不能确定,
而且每个元素的连续数量不一定相等。
并且调用GetPosValue() 函数,一次只能取一个位置的值。
|
能力值:
(RANK: )
|
-
-
18 楼
刚才没看清要求. 如果有统计信息, 比如"可以保证0、1、2、3每个byte连续出现的个数至少在20000以上", 那么可以以这个统计信息做为跨度, 依次读1, 20001, 40001, ..., 如果相邻两次的数据不同, 比如分别为0, 1, 那就按20000个0, 从20001开始是1, 这样输出(反正你说部分数据是可以忽略的).
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
兄弟谢谢你,
我做过这种方案,但有的连续次数不是2W,说不定只有1.3W,那么2W会跳过。
有的连续次数可能会是2.1W。现在最耗时的处理就是这种情况了,因为在这里要用二分。
而且这种情况出现频率非常高。
|
能力值:
( LV12,RANK:1000 )
|
-
-
20 楼
这是一个二分枚举的问题,其实就是在一个退化了的有序序列中进行二分查找,只是这个序列仅含0、1、2、3这4种值。兄弟知道怎么谷歌了吧!
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
多谢天易大侠指点,为了学习二分枚举,我翻了好多ACM题,但发现好多是英文题目。
还在继续google中。。
如果大家还有其它的思路,也来发表发表呀。
|
能力值:
( LV2,RANK:10 )
|
-
-
22 楼
既然楼主可以保证 0、1、2、3每个byte连续出现的个数至少在20000以上 何不以20000为分界线去查找呢?还是用二分,基本思路如下(不知可行否)取第一个位置的值假设是1,保存做比较值,然后取20000处的值,有两种情况,1.如果一样则在20000到40000之间进行二分查找,找到最后一个1并记录当前位置,规模缩小了,之后继续类似的操作,之前的值可以认为都是1(因为是连续的) 2.不一样则在0到20000之间进行二分查找,找到最后一个1,记录位置,规模缩小了,之后继续类似的操作....(有一个小问题就是如果规模小于1000(即连续的数量太小的的时候,可以忽略,暂时不考虑)) 以上是我的一点不成熟的想法,有待完善,希望大家多交流,如果有办法生成仿真数据的话,希望楼主告知,我们也可以在自己的机子上进行速度测试
|
能力值:
( LV2,RANK:10 )
|
-
-
23 楼
谢谢你。我用的第一总方法与你提供的思路差不多。
我是用
0
10000
20000
30000
这样的dwPos来累加的。。
我发现现在最耗时的就是二分查找的时候。 如果要生成测试文件很简单。
以2W为基数,用一个1.6W 到 2.3W之间的随机值来写0、1、2、3.生成一个2G的文件就可以了。我这里的数据是在硬件中取的,提供不了伪文件
|
能力值:
( LV2,RANK:10 )
|
-
-
24 楼
个人感觉二分查找不会费那么多时间,20000个数据查找14左右次就可以找到你要的数据了,一共需要进行 2的30次方 处以 20000 再乘以 14 次查询. 猜测可能是楼主代码的问题(具体不详),二分应该是查找最快的了,能否先把数据读到内存中在内存中进行查找呢? 周末有时间的话一定要写代码测试
|
能力值:
( LV2,RANK:10 )
|
-
-
25 楼
二分查找某个数的位置的确很快的。
但我现在的二分是找相邻的两个byte不等.
所以比查找某个数位置的二分要耗时一些。。
现在我是这样做的(假设发现2W和4W的位置不等了):
DWORD min = 2W;
DWORD max = 4W;
if (F(min) != F(max)) //这里只是做为递归的依据,
{
if ((F(max) == F(max-1)) && (F(max-1) != F(min)))
{//说明 max 处相邻的两个是 相等 的,并且 不等于 min的位置处,此时要max设为3W
....小值不变min = 2W,大值 max 为3W后递归....
}
if ((F(max) == F(max-1)) && (F(max-1) == F(min)))
{//说明 max 处相邻的两个是 相等 的,并且 等于 min处位置的值,
...此时要将 mix 设为3W,max 设为4W(这里的将max设为4W应该可以优化的,因为前面已经读过这里的值)...
}
if ((F(max) != F(max-1)) && (F(max-1) == F(min)))
{//max 不等于 max-1 ,说明找到分隔点了,直接返回max
return max
}
}
我的大致程序就是这样子的。感觉这个算法很迂回,
不行的,因为调用GetPosValue一次只能取一个byte.
如果我能全放到内存里*pBuf++ = GetPosValue(dwPos++);
相当于是全部遍历了一遍
|
|
|