分而治之算法

今天的算法是一个叫分而治之的思想,这个思想感觉对于程序优化,节约时间很有帮助,但是对于实际中的用途还是稍微差了点!这个思想很简单即使把一个大的程序,分成一小段一小段的区分步运行,这样的好处就是减少复杂度,比如我们要计算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在树莓派上的编程,等我完成了,我就将我自己翻译的说明书上传至网上,供大家下载并开发。

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