题目:数据有: (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.00002
100.10002
1999.00006
……
#10000
100.00010
……
1999.00040
2、对于S.txt中的每一一个数组,在P.txt中寻找“ 最相似”的数组,返回1千个编号(P.txt中的第几个数组)及“相似度”。每个结果占- -行,以 结尾,每行第一个数字为编号(一个整数),第二个数字为相似度(一个整数),中间用 分隔,共1千行,存为R.txt。输入相同的P.txt和S.txt,不同人写的程序输出的R.txt应该是一模一样的。R.txt格式示意如下:
3282288
4899152
5814124
4322124
......
3、"相似”的定义:两个数组里面有几个数字数值相差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 后得到的结果。
之后的输出并比较选择出最相似的过程,这里省略。欢迎有其他算法进行讨论交流。