一,排序
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Student{
char id[15];
int score;
}stu[30];
bool cmp(Student a,Student b){
if(a.score!=b.score) return a.score>b.score;//降序
else return strcmp(a.id,b.id)<0//字典序升序
}
int main(){
……
sort(stu,stu+10,cmp);
……
}
二,散列(hash)
将元素通过一个函数转换为一个整数,使得该整数可以尽量唯一地代表这个元素。
-----整数哈希------
1.直接定址法:bool hashTable[maxn]={false}
int hashTable[maxn]={0}
2.除留余数法:H(key)=key%mod 转换成不超过mod的整数。如果结果重合,用链地址法;
STL中的map;C++11有unordered_map;
3.二位整点哈希:Range
H(P)=x*Range+y
-----字符串哈希-----
1.字母为A-Z,视为0-25.把字符串视为26进制数,再转换成唯一的10进制数。
int hashfunc(char s[],int len){
int id=0;
for(int i=0;i<len;i++){
id=id*26+(s[i]-'A');
}
return id;
}
2.如果还有a-z就视为26-51
id=id*26+(s[i]-'A')+26;//判断是a-z
3.如果出现数字
同样增加进制;或者在字母转换为整数后,将末尾的数字拼接上去。
*例子:p110,给出n个字符串(3个字母),再给出m个字符串,问每个字符串在n个字符串中出现的次数。
#include<iostream>
using namespace std;
const int maxn=100;
char s[maxn][5],temp[5];
int hashTable[26*26*26+10]={0};
int hashFunc(char s[],int len){
int id=0;
for(int i=0;i<len;i++){
id=id*26+(s[i]-'A');
}
return id;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>s[i];
int id=hashFunc(s[i],3);
hashTable[id]++;
}
for(int i=0;i<m;i++){
cin>>temp;
int id=hashFunc(temp,3);
cout<<hashTable[id];
}
return 0;
}
三,递归,分治
将原问题分解成规模小的子问题,分别解决,最后合并成解。
1.斐波那契
#include<iostream>
int F(int n){
if(n==0||n==1) return 1;
else return F(n-1)+F(n-2);
}
int main(){
int n;
cin>>n;
cout<<F(n);
return 0;
}
2.全排列
---------------------------------------------------------------------------------------------------------------------------------
1.数位中含有 2、0、1、9
while(x)
{
if(x%10==2||x%10==0||x%10==1||x%10==9)return true;
x/=10;
}
return false;
3.有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?