2008年8月15日。
昨晚并没有完成理想中的任务,同时昨天也没有完习题第三题的解答。自己思考的结果没有完成,并且解法二也没有自己在机器上实现,所以今天用25分钟来完成习题3的思考以后,便是对后面几题的解答好了,先读一下昨天的思考。
简单总结下昨天的思路,如下图所示。
graph TD
A(思路) -->B(自己推导)
A -->C(同余定理)
B -->D(直接生成数列)
B -->E(生成单个随机数再生成数列)
%% 直接生成数列:
%% 用列举的方法将全部结果。结果列出,然后用生成随机数的方法,在里面取一个作为生成出的随机数列,这方法虽虽然有点蠢,但是不是不可行。
%% 同余定理:
%% 用取模运算加上移位运算来将一个数生成一个与当今函数看起来完全没有关系的书。
在这里又打算用同余定理来解这道题,即暂时放弃其他的想法。同时决定要在今日的晚些时候来实现由我自己写的同余定理的代码,调试并计算程序运行的时间,并与mp外的标准库函数的运行时间作一个简单的比较,只要不是太缓慢我都可以接受。
好了开始设计,先写一个简单的文本,等上机后面再根据数据量再来调整,移位的原理即是乘除。二进制的移位是乘除2,十进制的移位便是乘除10
首先用97 98 99来当做实验数据。
公式如下。
result = (n % 2333 * 13 + 56) // 10
%% 因计算器没有去于这个运算符,所以只能中午晚上用电脑做。
练习五:
如果严格规定空间为1M,那么该如何处理算法与运行时间又是多少?
我能想到的是两方面,一是优化现有的代码,第二重新设计。
%% (很好,讲想法都列出来了,有很大的进步。)
先说优化,我觉得可以将其分为两次来操作,因为共有一千万条数据,第一次就是先遍历前500万个,然后将第二次遍历后后面的500万个。
1 M = 1000 KB = 1000000 B = 8000000 bit
方法是可行的,时间就是以前的两倍,因为遍历了两次。
再说重新设计,我觉得也可以。因为这个问题是一个实际问题,它数据密集度可能很高,那么我们便可以将n个连续的1用二进制表示,那么便可节约很大的空间。
比如将连续的三个一转换成二进制,
例:数据[1,2,3,5,8,13]
则有,011101001000100 ,用(11)(二进制的3)表示有3个1是连续的
则有,01101001000100
可能这组数据不能说明问题,那我们来换一组数据。
[1,2,3,4,5,7,9,12,13,14,15]
0111110101001111
0,101,010100,100,
好了,现在出问题了,因为都是0与1,怎么判断那几个零与一是连起的就是个问题了。所以我觉得我们有必要引入‘n位二进制’这个概念了,那么问题来了,这个n该设置为多少?
2^32 = 4297967295
32位好像是足够了。
1M / 32bit = 250000
1M内存可以存放25万个int字节(int为四个字节,每个字节8位,则int为32位)
下面便要考虑数据的连续性,如果程序员先生的数据有25万次不连续,那么便不可以用这个方法,一千万个数,25万次不连续可能还是有点困难的吧。
25万 / 1千万 = 1 / 400 = 0.25 %
若连续的概率要超过99.75%,即400个数才可以有一次断裂,我觉得这还是难为人家了,但是将此方法写出来,便是有意义的。