【算法笔记入门篇】
第四章 二分法
- 在有序的序列中查找X;
- 求解序列中第一个大于等于x元素的位置
- 查找第一个大于x元素的位置
#include
#include
#include
using namespace std;
/*查找x*/
int searchX(int data[],int left, int right, int x){
int mid;
while(left<=right){
mid = (left + right)>>1;
if(data[mid] == x) return mid;
else if(data[mid] > x) right = mid + 1;
else left = mid;
}
return -1;
} /*
求解序列中第一个大于等于x元素的位置
*/
int solve(int data[],int left,int right, int x){
int mid;
while(left < right){ //推出循环的时候left == right
mid = (left + right)>>1;
if(data[mid] >= x){
right = mid;
}else {
left = mid + 1;
}
}
return left;
} /*查找第一个大于x元素的位置*/
int solve2(int data[],int left, int right, int x){
int mid;
while(left < right){
mid = (left + right)>>1;
if(data[mid] > x) right = mid;
else left = mid + 1;
}
return left;
} const int n = 10;
int main(){
int A[n] = {1,3,4,6,7,8,10,11,12,15};
int posX = searchX(A,0,n-1,10);
if(posX != -1){
printf("%d-%d\n",posX,A[posX]);
}else{
printf("cannot find x\n");
} int index = solve(A,0,n-1,9);
printf("%d-%d\n",index,A[index]);
index = solve2(A,0,n-1,6);
printf("%d-%d\n",index,A[index]);
return 0;
}
快速幂 【【算法笔记入门篇】】两种方法,其中迭代方法中采用分解的思路
比如求解2^13= 2^8 * 2^4 * 2^1;
#include
#include
#include
using namespace std;
typedef long long LL;
/*
求解快速幂 a^b%m;
*/
//迭代方法求解
LL binarypow(LL a,LL b,LL m){
LL ans = 1;
while(b > 0){
if(b & 1){
ans = ans * a % m;
}
a = a*a % m;
b>>=1;
}
return ans;
}
//递归方法
LL recursionpow(LL a,LL b, LL m){
if(b == 0) return 1;
if(b & 1) return a*recursionpow(a,b-1,m) % m;
else{
LL mul = recursionpow(a,b>>1,m);
//减少计算量
return mul*mul%m;
}
} int main(){
LL ans = binarypow(2,10,100000);
printf("%lld\n",ans);
ans = recursionpow(2,10,100000);
printf("%lld",ans);
return 0;
}
第五章数学问题(大整数+素数筛+分数问题) 大整数问题 在写一些编程的题目时候遇到的大整数问题,可以在c++语言做出如下定义并使用。java中有BigDecimal这个类,而在c++只能自己写一个基本的数据结构数组来保存数据。
代码如下:
#include
#include
#include
using namespace std;
/*
3 2 1
-1 2 3
-------*/
struct bign{
int d[1000];
int len;
bign(){
memset(d,0,sizeof(d));
//初始化数组
len = 0;
}
};
bign change(string s) {
bign c;
c.len = s.length();
for(int i = 0;
i < s.length();
i++){
c.d[i] = s[s.length()-i-1]-'0';
}
return c;
}
void printfArra(int d[],int len){
for(int i = 0;
i < len;
i++){
printf("%d",d[i]);
}
printf("\n");
}
//高精度加法
bign add(bign a, bign b){
bign c;
int cx = 0;
for(int i = 0;
i=1 && c.d[c.len-1] == 0) {
c.len--;
}
return c;
}
//大整数的乘法 一个整数*大整数 a*b
bign multiple(bign a, int b){
bign c;
int carry = 0;
for(int i = 0;
i < a.len;
i++){
int temp = a.d[i] * b + carry;
c.d[c.len++] = temp % 10;
carry = temp / 10;
}
while(carry){
c.d[c.len++] = carry % 10;
carry /= 10;
}
return c;
}
bign divide(bign a, int b, int &r){
//大整数除法 a/b 余数=r
bign c;
c.len = a.len;
for(int i = c.len-1;
i >= 0;
i--){
r = r*10 + a.d[i];
if(r < b) c.d[i] = 0;
else {
c.d[i] = r / b;
r = r % b;
}
}
while(c.len - 1>=1 && c.d[c.len-1]==0){//去除最高位是0的情况
c.len--;
}
return c;
}
void print(bign c){
for(int i = c.len-1;
i >= 0;
i--){
cout<>a>>b;
//输入两个数
bign n1 = change(a);
bign n2 = change(b);
bign c = add(n1,n2);
print(c);
*//*
string a,b;
cin>>a>>b;
//输入两个数
if(a.compare(b) < 0){
//如果字符串b>a则 做减法的时候要交换a,b,同时输出符号
swap(a,b);
cout<<"-";
}
bign c = devide(n1,n2);
print(c);
//打印相加结果
*/
/*
//大整数的乘法
string a;
int b;
cin>>a>>b;
bign n1 = change(a);
bign c = multiple(n1,b) ;
print(c);
*/
// 大整数除法
string a;
int b;
int r = 0;
cin>>a>>b;
bign n1 = change(a);
bignc = divide(n1,b,r);
print(c);
printf("\nr=%d:",r);
//余数 }
素数问题 经常遇到素数相关问题,有两种方法。前面的博客我也写过,今天在重新review一下。
#include
#include
#include
#include
using namespace std;
/*
方法1. 使用常规方法 n%i(i>=2 && i <= sqrt(n) )
方法2.使用素数筛法求解2-n范围内的素数 */
bool flag[1000];
//声明一个标记数组 素数筛法就是以空间换时间的列子
int prime[1000];
int index = 0;
//T1求解n以内的素数
void sovlePrime(int n){
memset(flag,true,sizeof(flag));
for(int i = 2;
i <= n;
i++) {
if(flag[i]){
prime[index++] = i;
for(int j = i;
j <= n;
j+=i){
flag[j] = false;
}
}
}
}
//T2求解质因子分解
struct Data{
int a,b;
//a是底数 b是指数
};
void devideeNum(int n) {
//将n分解成质数 如180=2^2*3^2*5;
sovlePrime(n);
//先求解质数
Data row[10];
int c = 0;
cout< 0){
cout<<"*";
}
cout<|
求最大公约数和最小公倍数 求解最大的公约数和最小公倍数代码,以及在次基础之上来求解分数的代码如下:
#include
#include
#include
using namespace std;
//算法笔记第五章
//求最大公约数3 63
//若a>bgcd(a,b)=gcd(b,a%b);
gcd(a,0) = a;
//推理 r=a-b*k;
假设d是a,b的最大公约数。则d也是r的公约数
//r=a%b;
得 d是b和a%b的最大公约数
//这种方法用的是欧几里得辗转相除法
int gcd(int a, int b) {
if(b == 0) return a;
else return gcd(b,a%b);
}//求最小公倍数ab/d,就是两个数的乘积/最大公约数
int lcm(int a, int b) {
return a/gcd(a,b)*b;
}
//5.3分数的四则运算
//分数表示 分子和分母
struct Fraction{
int up,down;
//up分子 down分母
};
//1.分数的化简
//down为非负数,若分数为负的,则让分子up 为负的
//如够分数恰为0 ,规定分子为0 分母为1
//分子分母没有除1以外的公约数
Fraction reduction(Fraction res) {
if(res.down < 0){
res.up = -res.up;
res.down = -res.down;
}
if(res.up == 0){
res.down =1;
}else{
int d = gcd(abs(res.up),abs(res.down));
res.up /= d;
res.down /= d;
}
return res;
}
//分数的加法
Fraction addF(Fraction a, Fraction b) {
Fraction c;
c.up = a.up*b.down + b.up*a.down;
c.down = a.down*b.down;
return reduction(c);
}
//分数的减法
Fraction deviceF(Fraction a, Fraction b) {
Fraction c;
c.up = a.up*b.down - b.up*a.down;
c.down = a.down*b.down;
return reduction(c);
}
//分数的乘法
Fraction multiF(Fraction a, Fraction b) {
Fraction c;
c.up = a.up*b.up;
c.down = a.down*b.down;
return reduction(c);
}
//分数的除法
Fraction devideF(Fraction a, Fraction b) {
Fraction c;
c.up = a.up * b.down;
c.down = a.down*b.up;
return reduction(c);
} int main(){
//求最小公倍数测试
//初始条件a>b
// int ans = lcm(9,3);
// printf("%d",ans);
// 分数的加法测试
/* Fraction a;
a.down = -4;
a.up = 4;
Fraction b = reduction(a);
printf("%d/%d",b.up,b.down);
*/
Fraction a,b;
a.up = 9;
a.down = -4;
b.up = 4;
b.down = 2;
Fraction c = addF(a,b);
printf("%d/%d",c.up,c.down);
return 0;
}
【注】这是我在准备考研复试时候,看《算法笔记》胡凡的书练习的代码,只想加深一下印象,因此把自己的东西输出一下。如有错误还请指之处,万分感谢!!!
推荐阅读
- 宽容谁
- 我要做大厨
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- 增长黑客的海盗法则
- 画画吗()
- 2019-02-13——今天谈梦想()
- 远去的风筝
- 三十年后的广场舞大爷
- 叙述作文
- 20190302|20190302 复盘翻盘