数组类似性计算

原由:有一师弟报考一老师,老师发来的测试题目。(应该是测试他的逻辑能力?)算法

题目:数据有: (1) P.txt文件, 内含从小到大排序的1万个数组; (2) S.txt文件, 内含从小到大排序的1千个数组。两个文件格式均为:(1)每一个数组开始为#00001,也就是读到一-行开始为#能够记为读到一个新数组。(2)小数点前有3到4位数字,小数点后有固定的5位数字。(3) 以/n换行。示意以下:数组

#00001测试

100.00001排序

100.10001遍历

……程序

1999.00005方法

#00002数据

100.00002tab

100.10002语言

1999.00006

……

#10000

100.00010

……

1999.00040

 

二、对于S.txt中的每一一个数组,在P.txt中寻找“ 最类似”的数组,返回1千个编号(P.txt中的第几个数组)及“类似度”。每一个结果占- -行,以\n结尾,每行第一个数字为编号(一个整数),第二个数字为类似度(一个整数),中间用\t分隔,共1千行,存为R.txt。输入相同的P.txt和S.txt,不一样人写的程序输出的R.txt应该是如出一辙的。R.txt格式示意以下:

3282288

4899152

5814124

4322124

......

三、"类似”的定义:两个数组里面有几个数字数值相差0.01之内。如S.txt中数组为[100,200,300],P.txt中数组为[200.00001 ,300.00001,1000],这两个数组类似度为2。“最类似”即为数值相差0.01之内的数字最多。注意,S.txt和P.txt数组里的数字只能用于计算一次类似度,不能重复计数,找数值最相近的数字进行计数。如S.txt中数组为[200,300],P.txt中数组为[200.00001 ,200.00002,1000],这两个数组.类似度为1。

要求:语言不限,输出计算结果。

这里简单说下个人思路,有更好的欢迎你们讨论下。

P => database

S => search data

{100.12345 : #P1} 正方向

{100.12346 : #P1}

......

{100.13345 : #P1}

-------------------

{100.11345 : #P1} 负方向

{100.11346 : #P1}

......

{100.12345 : #P1}

这里把 P 中每个数值的正负 0.01 范围内的数值所有遍历出来存成字典的形式。问题是,小数点后面保留了 5 位数,这样遍历存字典的操做会给计算时的储存带来很大压力。并且在遍历生成正负 0.01 范围内的数的时候也在浪费着计算时间。因此这个方法只是在最后的输出时节省了大量的时间。但总体上并无正真的作到“快速计算”。

如今对于每一个原始数值只保留两位小数如 100.12345 => 100.12,并将小数点后第三位数值信息保留在字典的值中,如:

{100.12 : 3#P1}

这时的key中少了上述步骤中的  100.11 的键值对,也少了 100.13 的键值对,因此将其增长进去并从新定义:

{100.11 : 3#P1} 降格 => {100.11 : jg3#P1}

{100.12 : 3#P1} 零格 => {100.12 : lg3#P1}

{100.13 : 3#P1} 升格 => {100.12 : sg3#P1}

取S中一数组的值 (记为s) 进行类似比较:

if(s == 100.11){

  s 小数点第三位 > 3 (原始数据小数点后第三位)

  print "类似度 + 1"

}

------------------------------------

if(s == 100.12){

  print "类似度 + 1"

}

------------------------------------

if(s == 100.13){

  s小数点第三位 < 3 (原始数据小数点后第三位)

  print "类似度 + 1"

}

------------------------------------

因为上述的字典中极可能是一对多的对应关系,因此将 jg,lg 和 sg 这些信息记录下来,方便比较时确实这个 key 是原始数据的保留小数点后两位的结果仍是经过升降 0.01 后获得的结果。

以后的输出并比较选择出最类似的过程,这里省略。欢迎有其余算法进行讨论交流。

相关文章
相关标签/搜索