基础算法总结

本文介绍了两种检测回文数的方法,包括数据翻转和字符串翻转,以及约瑟夫环问题的队列解法。同时,提到了C++中遍历输出vector的不同方式,字符与数字的转换,以及一些基础算法如Floyd算法和大数运算。文章还涵盖了日期和时间处理、字符串操作和算法应用等多个编程概念。
摘要由CSDN通过智能技术生成

目录

回文数

 方法一:正常数据翻转

方法二:利用字符串进行翻转

题目练习:

约瑟夫环

方法一:使用队列

练习题目:

其他总结


回文数

 方法一:正常数据翻转

#include<bits/stdc++.h>
using namespace std;
int main() {
	int x = 0;	
	ios::sync_with_stdio(false);
	cin >> x;
	int a = x;	//存储数据,为后期进行对比
	int b = 0;	//反转后的数据
	while (a != 0) {
		b = b * 10 + a % 10;
		a /= 10;
	}
	if (x == b) {
		cout << "是回文数!" << endl;
		cout << "x=" << x << endl;
		cout << "b=" << b << endl;
	}
	else {
		cout << "不是回文数!" << endl;
		cout << "x=" << x << endl;
		cout << "b=" << b << endl;
	}
	return 0;
}

方法二:利用字符串进行翻转

#include<bits/stdc++.h>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	int x;
	cin >> x;
	string s = to_string(x);	//将x转化为字符串
	string s1 = s;
	reverse(s1.begin(), s1.end());	//字符串进行翻转
	if (s == s1) {
		cout << "是回文数!" << endl;
		cout << "s1=" << s1 << endl;
		cout << "s=" << s << endl;
	}
	else {
		cout << "不是回文数!" << endl;
		cout << "s1=" << s1 << endl;
		cout << "s=" << s << endl;
	}
	return 0;
}

题目练习:

三角回文数

约瑟夫环

方法一:使用队列

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
queue<int>q;
int main()
{
  int n,k,m;
  cin>>n>>k>>m;
  int t=k%n;  //算出第一个位置
  for(int i=t;i<=n;++i) q.push(i);  //[t,n]进队列
  for(int i=1;i<t;++i) q.push(i);   //[1,t)进队列
  while(!q.empty()){
    for(int i=1;i<m;++i){   //计数 [1,m)的放到后面
      q.push(q.front());
      q.pop();
    }
    cout<<q.front()<<endl;  //输出第m个位置的数
    q.pop();
  }
  return 0;
}

练习题目:

约瑟夫环

其他总结

vector<>的遍历输出vector遍历

假如:vector<int> line={1,2,3,4,5,6,7,8,9};

方法一:for循环迭代器输出

for(vetcor<int>::const_iterator it=line.begin();it!=line.end();it++){

cout<<(*it)<<endl;

}

 for(auto it=line.begin();it!=line.end();it++){

cout<<(*it)<<endl;

}

方法二: for_each()函数

template <typename T>

void printer(const T& line) {

cout << line;

cout << endl;

}

void showvec(const vector<int>& line) {

for_each(line.cbegin(), line.cend(), printer<int>);

}

方法三:for区间遍历

for (auto lin : line) {

    cout << lin;

}

数字和字符的转化:

字符变成数字:

  1. 0==49;
  1. a==0;

a+0==145;

a+a==194;

#include<bits/stdc++.h>

using namespace std;

int main()

{

string str = "abc";

int shu[10];

memset(shu, 0, sizeof(shu));

for (int i = 0; i < str.length(); i++)

{

shu[i] = str[i] - '0'; // 49 50 51

shu[i] = str[i] - 'a';     // 0 1 2

cout << shu[i] << " ";

}

cout << endl;

for (int i = 0; i < str.length(); i++)

{

char k = shu[i]+ '0'; // a b c

char k = shu[i]+ 'a'; // a b c

cout << k << " ";

}

cout << endl;

return 0;

}

最短路径算法:(Floyd算法

template<typename T>

class FloydAlgorithm :public ShortestPathAlgorithm<T>

{

    void solve(std::vector<std::vector<T>>& roadArray)

    {

        int length = roadArray.size();

        for (int k = 0; k < length; k++)

        {

            for (int i = 0; i < length; i++)

            {

                for (int j = 0; j < length; j++)

                {

                    if (roadArray[i][k] + roadArray[k][j] < roadArray[i][j])

                    {

                        roadArray[i][j] = roadArray[i][k] + roadArray[k][j];

                    }

                }

            }

        }

    }

};

数字和字符相互转化:

/* string -> int*/

void sti(string& s, int& x) {

x = atoi(s.c_str());

}

/* int->string */

void its(string& s, int& x) {

stringstream ss;

ss << x;

s = ss.str();

}

判断是否是反转数:

bool rev(int n) {

    stringstream ss;

    ss << n;

    string s = ss.str();

    string t = s;

    reverse(s.begin(), s.end());

    if (s == t)  return true;

    return false;

}

数字转化字符串进行反转:

#include<bits/stdc++.h>

using namespace std;

int main()

{

    int n;

    cin >> n;

    stringstream ss;

    ss << n;

    string s = ss.str();

    reverse(s.begin(), s.end());

    cout << n << endl;

    cout << s << endl;

    //cout << ss << endl;

    return 0;

}

/*

输出结果是:

123456

123456

654321

*/

大小写转化:

/*小写字母=大写字母+32,则大写字母=小写字母-32*/

#include<bits/stdc++.h>

using namespace std;

int main() {

char s;

cin >> s;

//cout << char(int(s) - 32) << endl; //小写变成大写: a->A;

cout << char(int(s) + 32) << endl; //大写变成小写: A->a

return 0;

}

A-65  a-97

## 头文件 <cmath>

# 向上取整 ceil()

 

ceil(1.5)=2

ceil(0.5)=1

ceil(1)=1

# 向下取整 floor()

ceil(1.5)=1

ceil(0.5)=0

ceil(1)=1

判断是否是闰年:

bool  run(int y) {

if (y% 400 == 0 || (y % 100 != 0 && y % 4 == 0)) return true;

return false;

}

计算星期几:彩基姆拉尔森计算公式

星期为w,年份为y,月份为m,日期为d。

w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7

计算后把w+1就是真正的星期几了

注意:每年的1.2月份要当成上一年的13.14月计算,上述的除法均为整数。

判断月份:

day[31]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //2月份独自判断;

if(y%400==0||(y%100!=0 && y %4==0)) day[2]=29;

else day[2]=28;

31天的有:1,3,5,7,8,10,12;

30天的有:4,6,9,11;

       2月份独自判断;

判断是否是质数(素数):

bool zhi(int k) {

    for (int i = 2; i <= sqrt(k)+0.5; ++i) {

        if (k % i == 0)

            return false;

    }

    return true;

}

26个字符串小写:从下标0开始Z-Y

char str[26] = { 'Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y' };

26个字符串小写:从下标0开始z-y

char str[26] = { 'z,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y' };

最大公约数:

int gcd(int a, int b)

{

    if (b == 0) return a;

    return gcd(b, a % b);

}

最小公倍数:

int gcd(int a, int b)

{

    if (b == 0) return a;

    return gcd(b, a % b);

}

int lcm(int a, int b) { //最小公倍数

    return a * b /gcd(a, b);

}

二进制  八进制  十六进制 :

#include<bits/stdc++.h>

using namespace std;

int main() {

int a = 20;

printf("%d %o %x\n", a, a, a); //20 24 14  进制%d  八进制%o 十六进制%x

return 0;

}

二进制输出:

itoa(x, s, 2);

printf("%s\n",s);

N进制输出:

itoa(x, s, N);

printf("%s\n",s);

用法:

#include<bits/stdc++.h>

using namespace std;

int main() {

int x = 80;

char s[10];

itoa(x, s, 10);

cout << s << endl;

return 0;

}

求多个数乘积之后0的个数方法:

一.所谓正统思想,应该是看这些数当中2与5有多少对,因为乘法当中的10是由2×5得出的。将每一个数的因数中的2的个数统计出来,5同理,然后取两者的最小值即为对数。

“尺取法”

(1)啥情况适合用尺取法:涉及“(寻找任一个)区间”。

(2)想清楚两个点:①针对题意,怎么找到这个区间,即这个区间应满足怎样的条件。②关于start和end标识,什么时候start++,什么时候end++,什么时候应该跳出循环。anyway,要好好分析题意,结合题意设计。

求1-n个数 至少需要几个数做加减能全部得出:

例如:

1   1个(1:1)

7   3 个(1,4,6:1,6-4,6-4+1,4,6-1,6,6+1)

a   +1<=a<=

大数四则运算输入输出:

void input(vector<int>& v, string& a) {

    for (int i = a.size() - 1; i >= 0; i--) v.push_back(a[i] - '0');

}

void output(vector<int>& v) {

    for (int i = v.size() - 1; i >= 0; i--)cout << v[i];

}

大数相加算法:

/*大数相加*/

#include<iostream>

#include<vector>

using namespace std;

string a, b;

vector<int> add(vector<int>& A, vector<int>& B)

{

    for (int i = a.size() - 1; i >= 0; i--)

        A.push_back(a[i] - '0');

    for (int i = b.size() - 1; i >= 0; i--)

        B.push_back(b[i] - '0');

    int t = 0;

    vector<int> C;

    for (int i = 0; i < A.size() || i < B.size(); i++)

    {

        if (i < A.size())

            t += A[i];

        if (i < B.size())

            t += B[i];

        C.push_back(t % 10);

        t /= 10;

    }

    if (t)

        C.push_back(t);

    return C;

}

int main()

{

    vector<int> A, B, C;

    cin >> a >> b;

    

    C = add(A, B);

    for (int i = C.size() - 1; i >= 0; i--)

        cout << C[i];

    cout << endl;

    return 0;

}

大数相减算法:

#include<bits/stdc++.h>

using namespace std;

bool cmp_s(vector<int>& vec1, vector<int>& vec2)

{

    if (vec1.size() != vec2.size()) return vec1.size() >= vec2.size();

    for (int i = vec1.size() - 1; i >= 0; i--)

    {

        if (vec1[i] != vec2[i])return vec1[i] > vec2[i];

    }

    return true;

}

//c=vec1-vec2

vector<int> sub_s(vector<int>& vec1, vector<int>& vec2)

{

    vector<int>c;

    for (int i = 0, t = 0; i < vec1.size(); i++)

    {

        t = vec1[i] - t;

        if (i < vec2.size()) t = t - vec2[i];

        c.push_back((t + 10) % 10);

        if (t < 0)

        {

            t = 1;

        }

        else {

            t = 0;

        }

    }

    //去掉前导0

    while (c.size() > 1 && c.back() == 0)c.pop_back();

    return c;

}

int main()

{

    string a, b;

    cin >> a >> b;

    vector<int>vec1, vec2;

    for (int i = a.size() - 1; i >= 0; i--)vec1.push_back(a[i] - '0');

    for (int i = b.size() - 1; i >= 0; i--)vec2.push_back(b[i] - '0');

    if (cmp_s(vec1, vec2))

    {

        auto c = sub_s(vec1, vec2);

        for (int i = c.size() - 1; i >= 0; i--)printf("%d", c[i]);

    }

    else {

        auto c = sub_s(vec2, vec1);

        cout << "-";

        for (int i = c.size() - 1; i >= 0; i--)printf("%d", c[i]);

    }

}

大数相乘算法:

/*大数相乘  a>=0 && b>=0*/

#include<bits/stdc++.h>

using namespace std;

vector<int> mul_s(vector<int>& vec1, int& b)

{

    vector<int>c;

    int t = 0;

    for (int i = 0; i < vec1.size(); i++)

    {

        t = vec1[i] * b + t;

        c.push_back(t % 10);

        t /= 10;

    }

    while (t)

    {

        c.push_back(t % 10);

        t /= 10;

    }

    return c;

}

int main()

{

    string a;

    int b;

    cin >> a >> b;

    vector<int> vec1;

    for (int i = a.size() - 1; i >= 0; i--) vec1.push_back(a[i] - '0');

    auto x = mul_s(vec1, b);

    for (int i = x.size() - 1; i >= 0; i--) cout << x[i];

}

大数相除算法:

/*大数相除 vec>=0  b>=0 */

#include<bits/stdc++.h>

using namespace std;

vector<int> div_s(vector<int>& vec, int b, int& r)

{

    vector<int> c;//商

    for (int i = vec.size() - 1; i >= 0; i--)

    {

        r = r * 10 + vec[i];//余数*10+下一位

        c.push_back(r / b);

        r %= b;

    }

    //for(int i=0;i<=vec.size()-1;i++)cout<<vec[i];

    reverse(c.begin(), c.end());

    while (c.size() > 1 && c.back() == 0) c.pop_back();

    return c;

}

int main()

{

    string a;

    int b;

    cin >> a >> b;

    vector<int> vec;//被除数

    for (int i = a.size() - 1; i >= 0; i--) vec.push_back(a[i] - '0');

    int r = 0;//商

    auto c = div_s(vec, b, r);

    for (int i = c.size() - 1; i >= 0; i--)cout << c[i];

    cout << endl << r;

}

前N向求和的树状

/*前N向求和的树状*/

#include<bits/stdc++.h>

using namespace std;

int lowbit(int n) {

    return n - (n & (n - 1));

}

void updata(int n, int i, int v, int c[]){

    for (int k = i; k <= n; k += lowbit(k)) {

        c[k] += v;

    }

}

int getsum(int c[], int i) {

    int sum = 0;

    for (int k = i; k >= 1; k-=lowbit(k)) {

        sum += c[k];

    }

    return sum;

}

int main() {

    int arr[] = { 11,2,3,4,5,6,7,8,9 };

    int c[9];

    memset(c, 0, sizeof(c));

    for (int i = 0; i < 8; ++i) {

        updata(9, i + 1, arr[i], c);

    }

    cout << getsum(c,1) << endl;                            //11    

    cout << getsum(c, 5) -getsum(c,4)<< endl;               //5

    cout << getsum(c, 2) - getsum(c, 1) << endl;            //2

    return 0;

}

/*

------------

输出结果是:

11

5

2

----------

*/

哈夫曼距离:

D1(x1,y1)和D2(x2,y2)的距离计算公式

D(x,y)=|x1-x2|+|y1-y2|

其他距离计算参考:https://www.cnblogs.com/AlvinSui/p/8931074.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值