洗牌問題:洗一副撲克,有什麼好辦法?既能洗得均勻,又能洗得快?即相對於乙個檔案來說怎樣
高效率的實現亂序排列?
關於洗牌問題,其實已經有了乙個很好的shell解法,這裡另外給三個基於awk的方法,
有錯誤之處還請不吝指出。
方法一窮舉:
類似於窮舉法,構造乙個雜湊來記錄已經列印行出現行的次數,如果出現次數多於一
次則不進行處理,這樣可以防止重複,但缺點是加大了系統的開銷。
awk -v n=`sed -n '
$=' data` '
begin
}}'data
方法二變換:
基於陣列下標變換的辦法,即用陣列儲存每行的內容,通過陣列下標的變換
交換陣列的內容,效率好於方法一。
#! /usr/awk
begin
end}
function c(arr,len,i,j,t,x)
}方法三雜湊:
三個方法中最好的。
利用awk中雜湊的特性(詳細請看:info gawk 中的7.x ),只要構造乙個
隨機不重複的雜湊函式即可,因為乙個檔案每行的linenumber是獨一無二的,所
以用: 隨機數+每行linenumber ------對應------>那一行的內容
即為所構造的隨機函式。
從而有:
awk
'beginend
'data
測試環境:
pm 1
.4ghz cpu,40g硬碟,記憶體256m的laptop
suse
9.3 gnu bash version 3.00.16 gnu awk 3.1.4
產生乙個五十幾萬行的隨機檔案,大約有38m:
od /dev/urandom |dd count=75000 >data
拿效率較低的方法一來說:
time awk -v n=`sed -n '
$=' data` '
begin
}}'data
結果(檔案內容省略):
real 3m41.864s
user 0m34.224s
sys 0m2.102s
所以效率還是勉強可以接受的。
方法二的測試:
time awk -f awkfile datafile
結果(檔案內容省略):
real 2m26.487s
user 0m7.044s
sys 0m1.371s
效率明顯好於第乙個。
接著考察一下方法三的效率:
time awk
'beginend
'data
結果(檔案內容省略):
real 0m49.195s
user 0m5.318s
sys 0m1.301s
對於乙個38m的檔案來說已經相當不錯了。
玩的愉快!
隨機洗牌演算法
問題 給定乙個有序序列1 n,要你將其完全打亂,要求每個元素在任何乙個位置出現的概率均為1 n。解決方案 依次遍歷陣列,對第n個元素,以1 n的概率與前n個元素中的某個元素互換位置,最後生成的序列即滿足要求,1 n的概率可通過rand n實現。見如下程式 void swap int p,int q ...
隨機洗牌演算法
先看看肖舸老師的文章 隨機洗牌演算法複雜度的比較例項 其實我最初想到的也是那3個方法 1判斷生成的隨機數有沒有重複,2.生成一張布林表,3.雙隨機數。下面給出我的演算法 include include include using namespace std void randcard vector,...
2020 2 3 隨機洗牌程式設計
上機內容 c程式的編寫和執行 上機目的 掌握簡單c程式的編輯 編譯 連線和執行的一般過程 ps 借鑑了同學和網上的思路,感謝。我的程式 程式的版權和版本宣告部分 檔名稱 test.c 作 者 容瀟軍 完成日期 2020 年 2 月 3 日 版 本 號 v1.0 對任務及求解方法的描述部分 輸入描述 ...