算法设计技术
2015-10-03 22:27
274 查看
算法设计技术
问题:问题的输入是具有n个浮点数的向量x,输出是输入向量的任何连续子向量中的最大和。例如,如果输入向量包含下面10个元素:31,-41,59,26,-53,58,97,-93,-23,84
代码:
float arr[] = { 31, -41, 59, 26, -53, 58, 97, -93, -23, 84 };
// 立方算法 时间复杂度为T(n) = O(n^3)
float CubeMaxSubSum(const float *arr, const int N , int &begin , int &end)
{
float maxsofar = 0 ;
for (int i = 0; i < N; i++)
{
for (int j = i; j < N; j++)
{
float sum = 0;
for (int k = i; k <= j; k++)
{
sum += arr[k];
}
if (sum > maxsofar)
{
maxsofar = sum;
begin = i;
end = j;
}
}
}
return maxsofar;
}
// 平方算法1 时间复杂度T(n)=O(n^2);
float SquareMaxSubSum(const float *arr, const int N, int &begin, int &end)
{
float maxsofar = 0;
for (int i = 0; i < N; i++)
{
float sum = 0;
for (int j = i; j < N; j++)
{
sum += arr[j];
if (sum > maxsofar)
{
maxsofar = sum;
begin = i;
end = j;
}
}
}
return maxsofar;
}
#define N 10
// 平方算法2 时间复杂度T(n)=O(n^2);
float SquareTMaxSubSum(const float *arr, const int n, int &begin, int &end)
{
/*
* 下面3行代码解决 cumarr[-1] 的问题
*/
float realsum[N + 1] = { 0 };
float *cumarr = realsum + 1;
cumarr[-1] = 0;
for (int i = 0; i < n; i++)
{
cumarr[i] = cumarr[i - 1] + arr[i];
}
float maxsofar = 0;
for (int i = 0; i < n; i++)
{
float sum = 0;
for (int j = i; j < n; j++)
{
sum = cumarr[j] - cumarr[i-1];
if (sum > maxsofar)
{
maxsofar = sum;
begin = i;
end = j;
}
}
}
return maxsofar;
}
float max(float a, float b)
{
return a > b ? a : b;
}
// 分治算法 时间复杂度T(n)=O(nlogn);
/************************************************************************/
/*
* 算法说明:
*(1)当所有输入都是正数时,最大子向量就是整个输入向量
*(2)当所有输入都是负数时,最大子向量是空向量,和为0
*(3)当前处理情况是,输入序列有正有负
*/
/************************************************************************/
float DivideMaxSubSum(const float *arr, int left , int right)
{
if (left > right)
return 0;
if (left == right)
return 0 > arr[left] ? 0 : arr[left];
int middle = (left + right) / 2;
float lmax = 0, sum = 0;
for (int i = middle; i >= left; i--)
{
sum += arr[i];
lmax = lmax > sum ? lmax : sum;
}
float rmax = 0;
sum = 0;
for (int j = middle + 1; j <= right; j++)
{
sum += arr[j];
rmax = rmax > sum ? rmax : sum;
}
return max(max((lmax + rmax), DivideMaxSubSum(arr , left, middle)), DivideMaxSubSum(arr , middle + 1, right));
}
// 扫描算法 时间复杂度T(n)=O(n);
float ScanMaxSubSum(const float *arr, const int n )
{
float maxSoFar = 0, maxEndInHere = 0;
//该问题的关键在于maxEndInHere变量,它是结束位置i-1之前的最大子向量之和
for (int i = 0; i < n; i++)
{
maxEndInHere = max(maxEndInHere + arr[i], 0);
maxSoFar = max(maxSoFar, maxEndInHere);
}
return maxSoFar;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int begin = -1, end = -1;
int k = ScanMaxSubSum(arr, 10);
printf("k = %d\n", k);
return a.exec();
}
问题:问题的输入是具有n个浮点数的向量x,输出是输入向量的任何连续子向量中的最大和。例如,如果输入向量包含下面10个元素:31,-41,59,26,-53,58,97,-93,-23,84
代码:
float arr[] = { 31, -41, 59, 26, -53, 58, 97, -93, -23, 84 };
// 立方算法 时间复杂度为T(n) = O(n^3)
float CubeMaxSubSum(const float *arr, const int N , int &begin , int &end)
{
float maxsofar = 0 ;
for (int i = 0; i < N; i++)
{
for (int j = i; j < N; j++)
{
float sum = 0;
for (int k = i; k <= j; k++)
{
sum += arr[k];
}
if (sum > maxsofar)
{
maxsofar = sum;
begin = i;
end = j;
}
}
}
return maxsofar;
}
// 平方算法1 时间复杂度T(n)=O(n^2);
float SquareMaxSubSum(const float *arr, const int N, int &begin, int &end)
{
float maxsofar = 0;
for (int i = 0; i < N; i++)
{
float sum = 0;
for (int j = i; j < N; j++)
{
sum += arr[j];
if (sum > maxsofar)
{
maxsofar = sum;
begin = i;
end = j;
}
}
}
return maxsofar;
}
#define N 10
// 平方算法2 时间复杂度T(n)=O(n^2);
float SquareTMaxSubSum(const float *arr, const int n, int &begin, int &end)
{
/*
* 下面3行代码解决 cumarr[-1] 的问题
*/
float realsum[N + 1] = { 0 };
float *cumarr = realsum + 1;
cumarr[-1] = 0;
for (int i = 0; i < n; i++)
{
cumarr[i] = cumarr[i - 1] + arr[i];
}
float maxsofar = 0;
for (int i = 0; i < n; i++)
{
float sum = 0;
for (int j = i; j < n; j++)
{
sum = cumarr[j] - cumarr[i-1];
if (sum > maxsofar)
{
maxsofar = sum;
begin = i;
end = j;
}
}
}
return maxsofar;
}
float max(float a, float b)
{
return a > b ? a : b;
}
// 分治算法 时间复杂度T(n)=O(nlogn);
/************************************************************************/
/*
* 算法说明:
*(1)当所有输入都是正数时,最大子向量就是整个输入向量
*(2)当所有输入都是负数时,最大子向量是空向量,和为0
*(3)当前处理情况是,输入序列有正有负
*/
/************************************************************************/
float DivideMaxSubSum(const float *arr, int left , int right)
{
if (left > right)
return 0;
if (left == right)
return 0 > arr[left] ? 0 : arr[left];
int middle = (left + right) / 2;
float lmax = 0, sum = 0;
for (int i = middle; i >= left; i--)
{
sum += arr[i];
lmax = lmax > sum ? lmax : sum;
}
float rmax = 0;
sum = 0;
for (int j = middle + 1; j <= right; j++)
{
sum += arr[j];
rmax = rmax > sum ? rmax : sum;
}
return max(max((lmax + rmax), DivideMaxSubSum(arr , left, middle)), DivideMaxSubSum(arr , middle + 1, right));
}
// 扫描算法 时间复杂度T(n)=O(n);
float ScanMaxSubSum(const float *arr, const int n )
{
float maxSoFar = 0, maxEndInHere = 0;
//该问题的关键在于maxEndInHere变量,它是结束位置i-1之前的最大子向量之和
for (int i = 0; i < n; i++)
{
maxEndInHere = max(maxEndInHere + arr[i], 0);
maxSoFar = max(maxSoFar, maxEndInHere);
}
return maxSoFar;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int begin = -1, end = -1;
int k = ScanMaxSubSum(arr, 10);
printf("k = %d\n", k);
return a.exec();
}
相关文章推荐
- Linux对rm的误操作预防
- Spring MVC 解读——<mvc:annotation-driven/>
- 安卓控件使用系列32:ViewPager多页面滑动控件的使用方法1
- 用栈实现队列
- centos 正则,grep,egrep,流式编辑器 sed,awk -F 多个分隔符 通配符 特殊符号. * + ? 总结 问加星 cat -n nl 输出文件内容并加上行号 alias放~/.bash_profile 2015-4-10 第十三节课
- Mysql的Grant命令
- protocol小解(二)
- 树莓派raspberry Pi2 介绍
- 树形dp - Codeforces Round #322 (Div. 2) F Zublicanes and Mumocrates
- UVALive 3530 Martian Mining(贪心,dp)
- sql语言:如何查询字符串某个字符的个数?
- mybatis的逆向工程
- 二叉查找树中搜索区间
- 位图
- 删除xml某节点
- 一步一步学jQuery(三)
- 提取文件夹中.lib文件名到文本中
- 声明一个记录类型,定义记录类型变量,保存员工信息
- matlab中hold指令、figure指令及subplot指令的使用
- ubuntu安装dbench