原由:有一師弟報考一老師,老師發來的測試題目。(應該是測試他的邏輯能力?)算法
題目:數據有: (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 後獲得的結果。
以後的輸出並比較選擇出最類似的過程,這裏省略。歡迎有其餘算法進行討論交流。