今天开始补数据结构。其实以前也学过,都忘了,今天开始一点点补回来。
1. 什么是数据结构
数据结构由数据和结构组成,它是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科,数据结构是数据存储的方式。
2. 什么是算法
算法是处理数据的方法,通常我们通过分析算法的时间复杂度和空间复杂度来判断它的好坏。数据结构的不同就会导致算法的不同,数据结构的选择对算法效率会产生重大的影响,所以数据结构与算法紧密联系。如下面的程序算法时间复杂度为O(n^2+n^3) = O(n^3)
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
c[i][j]=0;//该步骤属于基本操作执行次数:n的平方次
for(k=1;k<=n;++k)
c[i][j]+=a[i][k]*b[k][j];//该步骤属于基本操作执行次数:n的三次方次
}
}
3. 练习
输入一组整数,求出这组数字子序列和中的最大值,只要求出最大子序列的和,不必求出最大值对应的序列。
最大子序列和:整数序列A1, A2,... An (可能有负数),求A1~An的一个子序列Ai~Aj,使得Ai到Aj的和最大。
例如:
序列:-2, 11, -4, 13, -5, 2, -5, -3, 12, -9,则最大子序列和为21。
序列:0, -3, 6, 8, -20, 21, 8, -9, 10, -1, 3, 6, 5,则最大子序列和为43。
代码实现如下,我用C++11
#include <vector> #include <iostream> // 输入一组整数,求出这组数字子序列和中的最大值,只要求出最大子序列的和,不必求出最大值对应的序列。 // 最大子序列和:整数序列A1, A2,... An (可能有负数),求A1~An的一个子序列Ai~Aj,使得Ai到Aj的和最大。 int max_seg_sum (const std::vector<int> & seq) { int outside_max = *(seq.cbegin()); for (auto i = seq.cbegin(); i != seq.cend(); ++i) { int inside_sum = (*i), inside_max = (*i); for (auto j = i+1; j != seq.cend(); ++j) { inside_sum += (*j); if (inside_sum > inside_max) inside_max = inside_sum; } if (inside_max > outside_max) outside_max = inside_max; } return outside_max; } int main(int argc, char const *argv[]) { std::vector<int> seq1 {-2, 11, -4, 13, -5, 2, -5, -3, 12, -9}; std::vector<int> seq2 {0, -3, 6, 8, -20, 21, 8, -9, 10, -1, 3, 6, 5}; std::cout << max_seg_sum(seq1) << std::endl; // ground truth: 21 std::cout << max_seg_sum(seq2) << std::endl; // ground truth: 43 return 0; }
总结:
1. 因为序列可能有负数,所以最大值初始化时不能初始为0, 可以初始化为序列或子序列的第一项!
2. 这个2重循环时间复杂度类似于选择排序,是O(n(n+1)/2) = O(n^2)
3. auto 类型只有C++11标准支持,CMakeLists.txt 中要加上:add_compile_options(-std=c++11)