声明:本文章知识来源于《算法笔记》,这是读后的归纳整理,供个人使用。
排序
排序的方法有很多,详见《数据结构与算法》。此处,仅记录上机时候的方便快捷的排序。
方法一
#include<cstdib>
int comp(const void *a,const void *b)
{
return *(int*)a-*(int*)b;//这里可以将a,b强制类型转化为特定的类型
}
qsort(array,n,sizeof(array),comp);
方法二
#include<algorithm>
using namespace std;
bool comp(Stu a,Stu b)
{
return a.score-b.score;
}
sort(array,array+n,comp);
散列
常用数据结构:hashFunc() 、hashTable[ ];哈希函数完成映射关系;哈希表进行性质统计。
将某一数据进行唯一标识。我们常用哈希函数来进行对特定数据的识别。例如:直接把输入的数作为数组的下标来对这个数的性质进行统计。(这是一种哈希函数,是对散列思想的一种运用)
所谓散列,将元素通过一个函数转化为整数,使得该整数可以尽量唯一地代表这个元素。
字符串hash,是指将一个字符串S映射为一个整数,使得该数可以尽可能唯一地代表字符串S。常用的方法是:先假设字符串均由大写字母A ~ Z构成。在这个基础上,不妨把A ~ Z视为0 ~ 25,这样就把26个大写字母对应到了26进制中。接着按照将26进制转化为10进制的方法,计算出一个整数,来唯一标识这个串。(若包括大写和小写字母,可以按照同样的思想,转为52进制)
int hashFunc(char S[], int len)
{
int id=0;
for(int i=0;i<len;i++)
{
id=id*26+(S[i]-'A');
}
return id;
}
分治
所谓分治,将原问题划分为若干个规模较小而结构与原问题相同或者相似的子问题,然后分别解决这些子问题,最后合并子问题的解,即可得到原问题的解。
分治法三步骤:
1、分解;2、解决;3、合并;
分治法是一种算法思想,既可以递归实现,也可以非递归实现。
递归:递归出口+递归函数。
在此,简单提一下递归的一种引伸:回溯法。回溯法就是在写递归函数的时候,在递归函数内又用此递归函数本身的时候,在这个递归语句后边写上“恢复现场”的语句。这只是回溯法的具体实现。它的思想是:**回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。祥见:链接。
贪心
所谓贪心,**它是求解一类最优化问题的方法。它总是考虑在当前状态下局部最优(或较好)的策略。**具体问题,具体分析。思想就是这么个思想。
二分法
机考中二分法的应用就是二分查找了。也算是分治法。直接看代码吧!
#include <stdio.h>
//A[]为严格递增序列,left为二分下界,right为二分上界,x为欲查询的数
//二分区间为左闭右闭的[left,right],传入的初值为[0,n-1]
int binarySearch(int A[],int left,int right,int x)
{
int mid;
while(left<=right)
{
mid = (left+right)/2;
if(A[mid]==x) return mid;
else if(A[mid] > x)
{
right = mid-1;
}
else
left= mid+1;
}
return -1; //查找失败,返回-1
}
int main()
{
const int n=10;
int A[n] = {1, 3, 4, 6, 7, 8, 10, 11. 12, 15};
printf("%d %d\n", binarySearch(A,0,n-1,6),binarySearch(A,0,n-1,9));
return 0;
}
记忆化搜索
记忆化算法:在求解的时候还是按着自顶向下的顺序,但是每求解一个状态,就将它的解保存下来,以后再次遇到这个状态的时候,就不必重新求解了。这种方法综合了搜索和动态规划两方面的优点,因而还是很有实用价值的。
简单地说,就是将频率大的数据,放在数组中,再遇到就直接取,大大降低了时间复杂度!具体题目:链接。
活用递推
每当见到题目后,都要分析全面后,再动手写代码。大多数题目的过程可能存在递推关系,如果找到了递推关系,那么复杂度就可以降低不少。例如PAT乙级题目“有几个PAT”,链接。分析这道题的时候,递推关系就是A左边P的个数乘以A右边T的个数就可以了。