找水王01
??? 題目:
??? 三人行設(shè)計了一個灌水論壇。信息學(xué)院的學(xué)生都喜歡在上面交流灌水,傳說在論壇上有一個“水王”,他不但喜歡發(fā)帖,還會回復(fù)其他ID發(fā)的每個帖子。坊間風(fēng)聞該“水王”發(fā)帖數(shù)目超過了帖子數(shù)目的一半。如果你有一張當(dāng)前論壇的帖子(包括回帖)列表,其中帖子的作者的ID也在其中,你能快速的找到這個傳說中的水王嗎?
??? 設(shè)計思想:
??? 通過對帖子列表進行遍歷,統(tǒng)計水王帖子的數(shù)目是最簡單的一種查找水王的方式,但是這種算法時間復(fù)雜度比較高。
??? 采用優(yōu)化的算法來解決這道問題,可以通過兩兩比較的方式來查找水王。如果當(dāng)下正在比較的兩個ID不同,則將其刪除,(不論水王的ID是否在這兩個之中),剩下的列表中,“水王”ID出現(xiàn)的次數(shù)仍然超過剩余總數(shù)的一半。通過不斷的重復(fù)這個過程,列表中的記錄數(shù)目就可以逐漸減少,從而在整體上降低算法的時間復(fù)雜度。
??? 程序概要設(shè)計:
??? 我的程序中首先假設(shè)列表中有十個用戶ID,用戶的ID號分別用0-9十個數(shù)字字符來代替,利用隨機函數(shù),生成N條記錄,即將用戶的ID號保存在一個長度為N的一維數(shù)組中。程序的起始同樣用隨機數(shù)生成了一個自定義的“水王”,在后續(xù)的程序中通過不重復(fù)隨機替換的方式,確保了一維數(shù)組中的自定義“水王”ID號在一半以上。查找水王的核心程序利用上述思想完成,程序的最后加了一個判斷,通過這個判斷可以清楚地知道自己的找水王程序是否得到了正確的結(jié)果。
??? 程序詳細設(shè)計見源代碼。
??? 源代碼如下:
//現(xiàn)有一張灌水論壇的帖子列表,“水王”發(fā)帖的數(shù)目超過了帖子數(shù)目的一半,找出水王ID //05-19,2016,Hailin Song#include<iostream> #include<stdlib.h> #include<time.h> using namespace std;#define N 100int main() {srand((int)time(NULL)); //定義時間種子int InitShuiWang = 0 + rand() % 10; //假設(shè)帖子列表中有10個ID號,分別用0-9這十個數(shù)字字符代替,自定義“水王”的IDcout << "自定義的“水王”ID為:";cout << InitShuiWang << endl; //輸出自定義的“水王”ID,同時測試“找水王”程序的結(jié)果是否正確cout << endl;int Tiezi[N]; //假設(shè)帖子列表中有N條記錄int location[N / 2 + 1];for (int i = 0; i < N; i++){Tiezi[i] = 0 + rand() % 10;}for (int i = 0; i < (N/2+1); i++) //循環(huán)執(zhí)行(N/2+1)次,確保帖子列表中有一半以上為“水王”的ID{location[i] = 0 + rand() % N; //確定帖子列表中隨機替換的位置for (int j = 0; j < i; j++){if (location[i] == location[j]) //確保隨機替換的位置不會發(fā)生重復(fù){location[i] = 0 + rand() % N;j = -1;}}Tiezi[location[i]] = InitShuiWang; //用“水王”的ID替換隨機產(chǎn)生的用戶的ID}cout << "帖子列表的ID如下所示:" << endl;for (int i = 0; i < N; i++){cout << Tiezi[i]<<" ";if (i % 10 == 9){cout << endl;}}cout << endl;//找水王程序的核心代碼,基本思想為:通過比較,每次刪除兩個不同的ID(不論是否包括水王),在剩下的列表中水王的ID出現(xiàn)次數(shù)仍在一半以上int SelectShuiWang; //通過程序找出的“水王”的IDint count=0; //用count記錄“水王”在帖子列表中出現(xiàn)的次數(shù)for (int i = 0; i < N; i++){if (0 == count) //如果count為零,則表示當(dāng)下還未找到真正的“水王”,或“水王”目前出現(xiàn)的次數(shù)小于等于其他ID用戶出現(xiàn)的次數(shù){SelectShuiWang = Tiezi[i];count = 1;}else{if (SelectShuiWang == Tiezi[i]){count++;}else{count--;}}}cout << "找水王程序找出的“水王”ID為:" << SelectShuiWang << endl;if (InitShuiWang == SelectShuiWang) //判斷找水王程序是否運行正確,是否能夠找出正確的“水王”ID{cout << "程序運行結(jié)果正確!" << endl;}else{cout << "程序運行結(jié)果錯誤!" << endl;}cout << endl;return 0; }??? 程序運行結(jié)果截圖如下所示:
???
??? 個人總結(jié):
??? 找水王算法和前段時間寫的動態(tài)規(guī)劃算法一樣,都是非常經(jīng)典,非常優(yōu)化的算法。其實這兩個算法之間有一些想通之處,都采用了一種轉(zhuǎn)化的方式來把問題簡化。當(dāng)我們采用傳統(tǒng)的思想思考問題時,雖然實現(xiàn)起來非常簡單,但是那樣的算法使得計算機需要做很多重復(fù)的工作。以本道題為例,優(yōu)化的算法抓住了簡化問題的一個最基本的點,那就是當(dāng)刪除兩個不同的ID號時,無論水王的ID號在不在這兩個之間,剩下的ID號列表中,水王的ID號仍然占據(jù)著一半以上。因此,這樣就可以把列表中的ID號數(shù)量逐漸減少,從而提升程序的執(zhí)行效率。程序就是這樣,采用不同的思想以及不同的算法,有時甚至是幾條不同的語句就能大大改善程序的性能,要想做到這一點,還需要從日后的學(xué)習(xí)中不斷地積累。
轉(zhuǎn)載于:https://www.cnblogs.com/hulidanxiang/p/5510148.html
總結(jié)
- 上一篇: [转]系统吞吐量(TPS)、用户并发量、
- 下一篇: 全选判空