分而治之算法

今天的算法是一個叫分而治之的思想,這個思想感覺對於程序優化,節約時間很有幫助,但是對於實際中的用途還是稍微差了點!這個思想很簡單即使把一個大的程序,分成一小段一小段的區分步運行,這樣的好處就是減少複雜度,比如我們要計算2的100次方,我們通常的思想就是

for (int i = 0 ; i < 100 ; i++)

{

temp *= 2 ;

}

好吧這麼計算真的很麻煩,我們可以這樣 

int    step = 2*2 ;

for (int i = 0 ;  i < 50 ; i++)

{

step  *= step ;

}

這樣可以節約一半的時間,所以他的效率還是蠻高的,但是除了這中比較簡單的實例以外,其他的分而治之的方法,真的是少子又少。下面講一個歸併排序和快速排序的方法

歸併排序:

感覺歸併排序就是插入排序,但是可能複雜度要小一些,他的思路就是先將數列分成兩組,再將每一組分成兩組,直至將數列全部分成一個數,再兩個兩次合併,再進行插入排序。由於不會插圖,這個排序本身並不好講,所以我也不說太多了。

快速排序:

就是選擇最後一個數,比他大的放左邊,比他小的放右邊,在後再對剩下的數組分別做這個方法的遞歸。


這裏面看到了一個快速乘積的算法叫做karasuba算法:(這個網上自己搜索去吧,他講的仔細)

下面是幾個分治算法的例題

就是一個籬笆上的木板高低不是很統一,要找出籬笆上最大的長方形面積?

#include <iostream>

#include <vector>


using namespace std;


int main()
{
cout << "請輸入測試數據個數 : ";
int times;
cin >> times ;
vector<int> data;
int temp;
int temp_num, final_num;
temp_num = 0;
final_num = 0;
for (int i = 0; i < times; i++)
{
cin >> temp;
data.push_back(temp); 
}


for (int i = 0; i < data.size(); i++)
{
temp_num = 0;
for (int j = i; j < data.size(); j++)
{
if (data.at(j) < data.at(i))
{
if (temp_num > final_num)
{
final_num = temp_num;
}
break;
}
temp_num += data.at(i);
if (temp_num > final_num && j == data.size()-1)
{
final_num = temp_num;
}
}
}
cout << "最大的和是" << final_num;
char ch;
cin >> ch;
return 0 ;
}


以上是我的答案,但是我真的想說自己的算法真的是太low了,因爲是個人就能想得到,書上寫的算法則是將這個問題分成3種情況

在選擇一塊木板的情況下,最大的長方形在左邊,在右邊,和在木板的兩邊  

即我們對每個木板進行訪問,同時判斷如果在訪問一塊木板的時,發現木板兩邊的木板都高於該木板,則繼續往外擴展,以此類推。


下一個問題:

粉絲見面會問題:

輸入一個樂隊組合成員的男女順序,再輸入粉絲團的男女順序,粉絲團每個人依次走過樂團成員,並與之擁抱。其中出現粉絲是男的,樂團的隊員的男的情況則改擁抱爲握手,請問樂團有多少次全體隊員都能擁抱:


#include <iostream>
#include <vector>
#include <string>


using namespace std;


int main()
{
cout << "輸入隊員序列M代表男W代表女:假設隊員數少於粉絲數";
string team;
cin >> team;
cout << "輸入粉絲序列M代表男W代表女:";
string fans;
cin >> fans;
vector<int>vector_team;
vector<int>vector_fans;
vector<int>vector_last;
int num = 0;
for (string::iterator it = team.begin(); it < team.end();it++)
{
if (*it == 'M')
vector_team.push_back(1);
else
vector_team.push_back(0);
}


for (string::iterator it = fans.begin(); it < fans.end(); it++)
{
if (*it == 'M')
vector_fans.push_back(1);
else
vector_fans.push_back(0);
}
for (int i = 0; i < vector_fans.size() - vector_team.size() + 1; i++)
{
int temp = 0;
for (int j = 0; j < vector_team.size(); j++)
{
temp += vector_team.at(vector_team.size() - 1 - j) * vector_fans.at(i + j);
}
vector_last.push_back(temp);
cout << endl << temp;
}
for (vector<int>::iterator it = vector_last.begin(); it < vector_last.end(); it++)
{
if (*it == 0)
{
num++;
}
}
cout << "同時擁抱次數" << num;


char a;
cin >> a;


return 0;
}

大概思路就是把女的看作0 ,把男的看作1 ,然後將兩個序列看作兩個數,然後將其相稱,判斷其中結果中爲0 的個數,其中比不包括不是全體隊員的情況。


代碼都很簡單,最近在玩matlab在樹莓派上的編程,等我完成了,我就將我自己翻譯的說明書上傳至網上,供大家下載並開發。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章