問題描述:
問題描述:令A【1…n】是一個整形序列,A中的整數a如果在A中出現的次數多於n/2,那麼稱a爲多數元素。試定義數組長度,從鍵盤隨機輸入n個數,設計算法尋找多數元素,若從在則輸出,否則輸出none。
—————————————————————————
思考過程:
我們利用majority算法來進行處理。Majority算法涉及到兩個核心步驟。
1.首先我們要了解一個基本歸納結果:如果一組元素中,某一元素爲多數元素(我們此時定義的多數元素爲元素個數過半的元素)。那麼當我們從元素集合中刪掉兩個不相同的元素,那麼之前的多數元素,依然是多數元素。關於這一點利用基本的數學知識可以分析:我們以三個元素爲例,假設有三個元素,其中X1爲多數元素,那麼存在下面這樣的關係:。當我們刪除掉一個X1,一個X2(或X3)後,我們將得到的關係式和1/2做減法,並且進行通分處理,得到下面這個式子:。因爲X1爲多數元素,所以X1大於其他元素的數量和,所以分子大於零。而分母部分,顯而易見將會大於2*1=2。所以這個式子大於零,那麼我們知道,X1類元素此時的個數是X1-1,仍然是多數元素。所以我們的歸納結果顯然是正確的。關於更多元素的關係式,我們不再進行推導。
這樣,關於這個歸納結果我們已經理解了,再次強調一下:如果一組元素中,某一元素爲多數元素(我們此時定義的多數元素爲元素個數過半的元素)。那麼當我們從元素集合中刪掉兩個不相同的元素,那麼之前的多數元素,依然是多數元素。
下面我們將利用這個結果設計算法。假設有一組元素A[ ],首先我們先取一個元素c=A[1],作爲初始假設(假設這個元素爲多數元素),那麼我們此時去一個標準值count=1。即假設元素在當前元素空間內已經有count=1個。我們將A[2]與c進行比較,如果相等,那麼count+1,如果不相等,那麼我們將count-1。然後我們進行判斷,如果我們的元素空間沒有比較結束並且count>0,那麼我們繼續將A[3]與c進行比較,循環據此進行。如果循環條件不再符合,count=0,那麼證明我們剛剛處理的元素空間中,有一個元素佔了一半,那麼我們正好可以將剛剛處理的元素兩兩分組,且每組都是不同元素,我們現在放棄剛纔處理的元素。在剩下的元素空間中,多數元素並未發生變化,所以我們對剩下的元素空間進行剛剛的處理。這樣就形成了遞歸。最終,我們遍歷了整個元素空間,得到一個元素C。第一個核心步驟就已經完成了,我們將其命名爲candidate過程。
2.下面我們進行第二個步驟,我們剛剛得到的元素C可能是多數元素,當然也可能是佔空間一半的元素,所以進行一個簡單比較,計算一下C的個數是否大於1/2,如果爲多數元素,那麼返回c,如果不是多數元素,那麼返回NONE。第二個核心步驟也已完成。
—————————————————————————-
僞代碼:
Majority過程:
1.c=candidate(1)
2.count=0
3.for j=1 to n
4. if A[j]=c then count=count+1
5.end for
6.if count>n/2 then return c
7.else return none
Candidate過程:
1.candidate(m)
2.j=m;c=A[m];count=1
3.while j0
j=j+1
4.if A[j]=c then count=count+1
5.else count=count-1
6.end while
7.if j=n then return c
8.else return candidate(j+1)
———————————————————————————————————-
源代碼:
程序由python 3.5 環境完成,並由pycharm community 2017 editor IDE 進行編譯
import xlrd
from numpy import *
def dataget(exlname,sheetname):
ori = xlrd.open_workbook(exlname)
table = ori.sheet_by_name(sheetname)
data=[]
for i in range(0, table.nrows):
data.append(table.row_values(i))
return data
def condidate(m,A):
j=m
c=A[m]
count=1
while j<len(A)-1 and count>0:
j=j+1
if A[j]==c:
count=count+1
else:
count=count-1
if j==len(A)-1:
return c
else:
return condidate(j+1,A)
def majority(A):
c=condidate(0,A)
count=0
for i in range(0,len(A)-1):
if A[i]==c:
count=count+1
if count>len(A)/2:
return c
else:
return None
if __name__ == '__main__':
data=dataget('majority data.xlsx','Sheet1')
result=majority(data)
print(result)
———————————————————————————-
代碼講解:
代碼共有四個部分
.
除了candidate()函數和majority()函數外,我們還定義了一個dataget()函數,用來讀取數據。我們在一個名稱爲“majority data.xls”的Excel表格中的Sheet1的A1列中輸入我們的數據,保存並放在程序目錄中,然後運行程序。