【C++】算法基础篇---基础算法

C++ 算法:从基础到高级 C++ 是一种功能强大且高效的编程语言,广泛应用于系统编程、游戏开发、嵌入式系统以及高性能计算等领域。算法是程序设计的核心,掌握常用算法是成为优秀 C++ 程序员的必备技能。本文将介绍一些常用的 C++ 算法,从基础到高级,帮助读者逐步提升算法能力。C++ 标准库没有直接提供图算法的实现,但可以使用第三方库(如 Boost Graph Library)或自己实现。排序算法是最基本的算法之一,C++ 标准库提供了多种排序算法。典型的例子是斐波那契数列。,它使用了混合排序算法(通常是快速排序和堆排序的结合)。 阅读详情

1.排序

1.1 模板

(1)快速排序

基于分治法,不稳定的,时间复杂度O(NlogN)

a.确定分界点  可以选择         q[ l ]   q[ ( l + r ) / 2 ]     q[ r ]       随机

b.调整区件    小于等于x的在左边    大于等于x的在右边

c.递归处理左右两边

----------------------------第一种----------------------------
class Solution {
public:
    void quick_sort(vector<int>& nums,int l,int r){
        if(l>=r) return;
        int q=nums[l],i=l-1,j=r+1;
        while(i<j){
           do i++; while(nums[i]<q);
           do j--; while(nums[j]>q);
           if(i<j)swap(nums[i],nums[j]);
        }
        quick_sort(nums,l,j);
        quick_sort(nums,j+1,r);
    }
    vector<int> sortArray(vector<int>& nums) {
        quick_sort(nums,0,nums.size()-1);
        return nums;
    }
};
----------------------------第二种----------------------------
class Solution {
public:
    void quick_sort(vector<int>& nums,int l,int r){
        if(l>=r) return;
        int q=nums[l],i=l,j=r;
        while(i<j){
            while(nums[++i]<q);
            while(nums[--j]>q);
            if(i<j){
                swap(nums[i],nums[j]);
            }
        }
        quick_sort(nums,l,j);
        quick_sort(nums,j+1,r);
    }
    vector<int> sortArray(vector<int>& nums) {
        quick_sort(nums,0,nums.size()-1);
        return nums;
    }
};

可否变为稳定的:可以的,使用pair带上数的下标 

(2)归并排序

基于分治法,稳定的,时间复杂度O(NlogN)

a.确定分界点     mid=( l + r ) / 2

b.递归排序         left    right 

c.归并两边      合二为一

class Solution {
public:
    int tmp[100010];
    void merge_sort(vector<int>& nums,int l,int r){
        if(l>=r) return;
        int mid=(l+r)/2;;
        merge_sort(nums,l,mid);
        merge_sort(nums,mid+1,r);
        int k=0,i=l,j=mid+1;
        while(i<=mid&&j<=r){
            if(nums[i]<=nums[j]) tmp[k++]=nums[i++];
            else tmp[k++]=nums[j++];
        }
        while(i<=mid) tmp[k++]=nums[i++];
        while(j<=r) tmp[k++]=nums[j++];
        for(int i=l,j=0;i<=r;i++,j++){
            nums[i]=tmp[j];
        }
        
    }
    vector<int> sortArray(vector<int>& nums) {
        merge_sort(nums,0,nums.size()-1);
        return nums;
    }
};

1.2 例题

题目:

        给定一个长度为n的整数数列,以及一个整数k,请用快速选择算法求出数列的第k小的数是多少。

输入格式:
        第一行包含两个整数 n 和 k。第二行包含 n 个整数(所有整数均在1~109范围内),表示整数数列。

输出格式:
        输出一个整数,表示数列的第k小数。

数据范围:
        1≤n≤100000,1≤k≤n

输入样例:

5 3
2 4 1 5 3

输出样例:

3

解答:

#include<iostream>
#include<algorithm>

using namespace std;

const int N=100010;

int q[N];
int n,k;

int quick_k_sort(int l,int r,int k){
    if(l>=r) return q[l];
    int x=q[l],i=l-1,j=r+1;
    while(i<j){
        do i++; while(q[i]<x);
        do j--; while(q[j]>x);
        if(i<j) swap(q[i],q[j]);
    }
    int sl=j-l+1;
    if(k<=sl) return quick_k_sort(l,j,k);
    else return quick_k_sort(j+1,r,k-sl);
}
int main(){
    cin>>n>>k;
    for(int i=0;i<n;i++) cin>>q[i];
    cout<<quick_k_sort(0,n-1,k);
    return 0;
}

题目:
给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量。

逆序对的定义如下:对于数列的第 i 个和第 j  个元素,如果满足 i < j且 a [ i ] > a [ j ] ,则其为一个逆序对;否则不是。

输入格式:

第一行包含整数 n nn,表示数列的长度。

第二行包含 n nn 个整数,表示整个数列。

输出格式:

输出一个整数,表示逆序对的个数。

数据范围:

1 ≤ n ≤ 100000 ,数列中的元素的取值范围 [ 1 , 10 ^9 ]

输入样例:

6
2 3 4 5 6 1

输出样例:

5

解答:

#include<iostream>
#include<algorithm>

using namespace std;
typedef long long LL;
const int N=100010;

int q[N],tmp[N];
int n;

LL merge_sort(int l,int r){
    if(l>=r) return 0;
    int mid= l + r >>1;
    LL res=merge_sort(l,mid)+merge_sort(mid+1,r);
    int i=l,j=mid+1,k=0;
    while(i<=mid&&j<=r){
        if(q[i]<q[j]) tmp[k++]=q[i++];
        else {
            tmp[k++]=q[j++];
            res+=mid-i+1;
        }
    }
    while(i<=mid) tmp[k++]=q[i++];
    while(j<=r) tmp[k++]=q[j++];
    
    for(int t=l,p=0;t<=r;t++,p++) q[t]=tmp[p];
    return res;
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++) cin>>q[i];
    cout<<merge_sort(0,n-1);
    return 0;
}

2.二分查找

2.1  模板

算法思路:假设目标值在闭区间[l, r]中, 每次将区间长度缩小一半,当l = r时,我们就找到了目标值。

2.1.1 整数排序

2.1.1.1 求一个数
int bsearch_left(int l, int r)
{
    while(l<r){
          mid=(l+r)>>1;
          if(q[mid]==goal) return mid;
          else if(q[mid]>goal) r=mid;
          else l=mid+1;
    }
    return -1;
}
2.1.1.2 左分界点

当我们将区间[ l ,  r ]划分成[ l ,  mid ]和[ mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。

int bsearch_left(int l, int r)
{
    while(l<r){
          mid=(l+r)>>1;
          if(check(mid)) r=mid; 
          else l=mid+1; 
    }
    return l;
}
2.1.1.3 右分界点

当我们将区间 [l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。

int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

2.1.2 浮点数排序

double bsearch(double l, double r)
{
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求
    while (r - l > eps)
    {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}

2.2 例题

题目描述:

        给定一个浮点数n,求它的三次方根。

输入格式:

        共一行,包含一个浮点数n。

输出格式:

        共一行,包含一个浮点数,表示问题的解。

        注意,结果保留6位小数。

数据范围:  −10000 ≤ n ≤10000

输入样例:

1000.00 

输出样例:

10.000000 

解答:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int main(){
    int x;
    cin>>x;
    double l=-10000,r=10000;
    while(r-l>1e-8){
        double mid=(l+r)/2;
        if(mid*mid*mid<=x) l=mid;
        else r=mid;
    }
    printf("%lf",l);
    return 0;
}

3.高精度

3.1 存储与输入输出

输入

string a,b;
vector<int> A,B;
cin>>a>>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');

输出

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

注意事项:

高精度加法:

  • 倒叙输入,倒序输出,但中间是正着运算;
  • 相加之后的进位处理;

高精度减法:

  • 考虑结果出现的正情况;
  • 前导0的处理;
  • 考虑减法的借位处理;

高精度乘法:

  • 前导0的处理(0被相乘);
  • 可以将乘法单个位数相乘再转化成加法的思想;
  • 此时题目中没有涉及到负数的情况。如出现负数,只需考虑两个字符串第一位是否为负号,然后结尾特殊判断一下即可;

高精度除法:(高精度÷低精度)

  • 输入、计算、输出、需要同时逆序或同时正序;
  • 前导0的处理;
  • 不能考虑进位的情况

3.2 高精度加法

3.2.1 模板

大数A,B读入时使用字符串string读入,然后从各位开始按序放入整数数组中,注意存入整数需要减掉‘0’

// C = A + B, A >= 0, B >= 0
vector<int> add(vector<int> &A, vector<int> &B)
{
    vector<int> C;
    int t = 0;
    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;
}

3.2.2 例题 

题目:

给定两个正整数(不含前导 0),计算它们的和。

输入格式:

共两行,每行包含一个整数。

输出格式:

共一行,包含所求的和。

数据范围:

1≤整数长度≤100000

输入样例:

12
23

输出样例:

35

解答:

#include<iostream>
#include<vector>
using namespace std;

const int N = 100010;
vector<int> A , B;
 
vector<int> add(vector<int> &A,vector<int> &B){
    vector<int> C;
    int t=0;//进位
    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()
{
	string n, m;
	cin >> n >> m;
	for (int i = n.size()-1; i >=0; i--)	A.push_back(n[i]-'0');
    for (int i = m.size()-1; i >=0; i--)	B.push_back(m[i]-'0');
	vector<int> C=add(A,B);
	for(int i = C.size()-1; i >=0; i--) cout<<C[i];
	return 0;
}

3.3 高精度减法

3.3.1 模板

// C = A - B, 满足A >= B, A >= 0, B >= 0
vector<int> sub(vector<int> &A, vector<int> &B)
{
    vector<int> C;
    for (int i = 0, t = 0; i < A.size(); i ++ )
    {
        t = A[i] - t;
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        if (t < 0) t = 1;
        else t = 0;
    }
    //如果答案不为0,则删去前导0

    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

3.3.2 例题

题目:
给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。

输入格式:
共两行,每行包含一个整数。

输出格式:
共一行,包含所求的差。

数据范围:
1≤整数长度≤100000

输入样例:

32
11

输出样例:

21 

解答:

#include<iostream>
#include<vector>
using namespace std;

const int N = 100010;
vector<int> A , B;

bool cmp(vector<int> &A,vector<int> &B){
    if(A.size()!=B.size()) return A.size()>B.size();
    for(int i=A.size()-1;i>=0;i--){
        if(A[i]!=B[i]) return A[i]>B[i];
    }
    return true;
}

vector<int> sub(vector<int> &A,vector<int> &B){
    vector<int> C;
    int t=0;//借位
    for(int i=0;i<A.size();i++){
        t=A[i]-t;
        if(i<B.size()) t-=B[i];
        C.push_back((t+10)%10);
        if(t<0) t=1;
        else t=0;
    }
    while(C.size()>1&&C.back()==0) C.pop_back();
    return C;
}

int main()
{
	string n, m;
	cin >> n >> m;
	for (int i = n.size()-1; i >=0; i--)	A.push_back(n[i]-'0');
    for (int i = m.size()-1; i >=0; i--)	B.push_back(m[i]-'0');
    vector<int> C;
    if(cmp(A,B)){
        C=sub(A,B);
    }else{
        C=sub(B,A);
        cout<<"-";
    }
	
	for(int i = C.size()-1; i >=0; i--) cout<<C[i];
	return 0;
}

3.4 高精度乘低精度

3.4.1 模板

// C = A * b, A >= 0, b >= 0
vector<int> mul(vector<int> &A, int b)
{
    vector<int> C;

    int t = 0;
    for (int i = 0; i < A.size() || t; i ++ )
    {
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }

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

    return C;
}

3.4.2 例题

题目:

给定两个非负整数(不含前导 0) A 和 B,请你计算 A×B的值。

输入格式:
共两行,第一行包含整数 A,第二行包含整数 B。

输出格式:
共一行,包含 A×BA×B 的值。

数据范围:
1≤A的长度≤100000  0≤B≤100000 

输入样例:

2
3

输出样例:

6

解答:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;


const int N = 100010;
vector<int> A , B;


vector<int> mul(vector<int> &A,int b){
    vector<int> C;
    int t=0;//进位位
    for(int i=0;i<A.size()||t;i++){
        //当数字处理完且进位t也处理完后即可结束循环
        if(i<A.size()) t+=A[i]*b;
        C.push_back(t%10);
        t/=10;
    }
    while(C.size()>1&&C.back()==0) C.pop_back();
    return C;
}

int main()
{
	string n;
	int m;
	cin >> n >> m;
	for (int i = n.size()-1; i >=0; i--)	A.push_back(n[i]-'0');
    vector<int> C=mul(A,m);
	for(int i = C.size()-1; i >=0; i--) cout<<C[i];
	return 0;
}

3.5 高精度除以低精度

3.5.1 模板

// A / b = C ... r, A >= 0, b > 0
vector<int> div(vector<int> &A, int b, int &r)
{
    vector<int> C;
    r = 0;
    for (int i = A.size() - 1; i >= 0; i -- )
    {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    reverse(C.begin(), C.end());
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

3.5.2 例题

题目:
给定两个非负整数(不含前导 0)A ,B ,请你计算 A / B 的商和余数。

输入格式:
共两行,第一行包含整数 A,第二行包含整数B。

输出格式:
共两行,第一行输出所求的商,第二行输出所求余数。

数据范围:
1 ≤ A 的长度 ≤ 100000 ,1 ≤ B ≤ 10000 ,B 一定不为 0
 

输入样例:

7
2

输出样例:

3
1

解答:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;


const int N = 100010;
vector<int> A , B;


vector<int> div(vector<int> &A,int b,int &r){
    vector<int> C;

    for(int i=A.size()-1;i>=0;i--){
        //当数字处理完且进位t也处理完后即可结束循环
        r=r*10+A[i];
        C.push_back(r/b);
        r%=b;
    }
    reverse(C.begin(),C.end());
    while(C.size()>1&&C.back()==0) C.pop_back();
    return C;
}

int main()
{
	string n;
	int b,r=0;
	cin >> n >> b;
	for (int i = n.size()-1; i >=0; i--)	A.push_back(n[i]-'0');
    vector<int> C=div(A,b,r);
	for(int i = C.size()-1; i >=0; i--) cout<<C[i];
	cout<<endl<<r<<endl;
	return 0;
}

4.前缀和和差分

前缀和与差分 图文并茂 超详细整理(全网最通俗易懂)-优快云博客

前缀和问题,一般下标从1开始,为了减一之后不会越界

4.1 一维前缀和

4.1.1 模板

原数为  a1  a2  a3   a4   a5…

前缀和  Si=a1+a2+a3+…+ai

求区间前缀和[l,r]

S_{r}- S_{l-1}

前缀和:S[i] = a[1] + a[2] + ... a[i]=S[i-1]+a[i]
部分和:a[l] + ... + a[r] = S[r] - S[l - 1]

4.1.2 例题

 题目:

输入一个长度为n的整数序列。
接下来再输入m个询问,每个询问输入一对l, r。
对于每个询问,输出原序列中从第l个数到第r个数的和。
输入格式:
第一行包含两个整数n和m。
第二行包含n个整数,表示整数数列。
接下来m行,每行包含两个整数l和r,表示一个询问的区间范围。
输出格式:
共m行,每行输出一个询问的结果。
数据范围:
1≤l≤r≤n,
1≤n,m≤100000,
−1000≤数列中元素的值≤1000

输入样例:

5 3
2 1 3 6 4
1 2
1 3
2 4

输出样例:

3
6
10

解答:

#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

const int N=100010;
int q[N],S[N];

int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>q[i];
    for(int i=1;i<=n;i++) S[i]=S[i-1]+q[i];
    while(m--){
        int l,r;
        cin>>l>>r;
        cout<<S[r]-S[l-1]<<endl;
    }
    return 0;
}

4.2 二维前缀和

4.2.1 模板

S[i, j] = 第i行j列格子左上部分所有元素的和
前缀和:S[i, j] = S[i-1,j]+S[i,j-1]-S[i-1,j-1]+a[i,j]
以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
部分和:S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]

首先给定一个原数组a:a[1], a[2], a[3],,,,,, a[n];

然后我们构造一个数组b : b[1], b[2], b[3],,,,,, b[i];

使得 a[i] = b[1] + b[2] + b[3] + ,,,,,, + b[i]

也就是说,a数组是b数组的前缀和数组,反过来我们把b数组叫做a数组的差分数组。换句话说,每一个a[i]都是b数组中从头开始的一段区间和。

4.2.2 例题

 题目:

输入一个n行m列的整数矩阵,再输入q个询问,每个询问包含四个整数x1, y1, x2, y2,表示一个子矩阵的左上角坐标和右下角坐标。

对于每个询问输出子矩阵中所有数的和。

输入格式:
第一行包含三个整数n,m,q。

接下来n行,每行包含m个整数,表示整数矩阵。

接下来q行,每行包含四个整数x1, y1, x2, y2,表示一组询问。

输出格式:

共q行,每行输出一个询问的结果。

数据范围:
1≤n,m≤1000,
1≤q≤200000,
1≤x1≤x2≤n,
1≤y1≤y2≤m,
−1000≤矩阵内元素的值≤1000

输入样例:

3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4

输出样例:

17
27
21

解答:

#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

const int N=1010;
int a[N][N],S[N][N];

int main(){
    int n,m,q;
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++)
            cin>>a[i][j];
            
    for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++)
            S[i][j]=S[i-1][j]+S[i][j-1]-S[i-1][j-1]+a[i][j];
            
    while(q--){
        int x1,y1,x2,y2;
        cin>>x1>>y1>>x2>>y2;
        cout<<S[x2][y2]-S[x1-1][y2]-S[x2][y1-1]+S[x1-1][y1-1]<<endl;
    }
    
    return 0;
}

4.3 一维差分

4.3.1 模板

给区间[l, r]中的每个数加上c:
                    B[l] += c, B[r + 1] -= c

4.3.2 例题

题目:

输入一个长度为n的整数序列。
接下来输入m个操作,每个操作包含三个整数l, r, c,表示将序列中[l, r]之间的每个数加上c。
请你输出进行完所有操作后的序列。

输入格式:
第一行包含两个整数n和m。
第二行包含n个整数,表示整数序列。
接下来m行,每行包含三个整数l,r,c,表示一个操作。
输出格式:
共一行,包含n个整数,表示最终序列。
数据范围:
1≤n,m≤100000,
1≤l≤r≤n,
−1000≤c≤1000,
−1000≤整数序列中元素的值≤1000

输入样例:

6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1

输出样例:

3 4 5 3 4 2

解答:

#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

const int N=100010;
int a[N],b[N];

void insert(int l,int r ,int c){
    b[l]+=c;
    b[r+1]-=c;
}

int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
            
    for(int i=1;i<=n;i++) insert(i,i,a[i]);
            
    while(m--){
        int l,r,c;
        cin>>l>>r>>c;
        insert(l,r,c);
    }

    for(int i=1;i<=n;i++){
        a[i]=a[i-1]+b[i];
        cout<<a[i]<<" ";
    }
    return 0;
}

4.4 二维差分

4.4.1 模板

给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c:
                    S[x1, y1] += c
                    S[x2 + 1, y1] -= c
                    S[x1, y2 + 1] -= c
                    S[x2 + 1, y2 + 1] += c

4.4.2 例题

题目:

输入一个n行m列的整数矩阵,再输入q个操作,每个操作包含五个整数x1, y1, x2, y2, c,其中(x1, y1)和(x2, y2)表示一个子矩阵的左上角坐标和右下角坐标。
每个操作都要将选中的子矩阵中的每个元素的值加上c。
请你将进行完所有操作后的矩阵输出。
输入格式:
第一行包含整数n, m, q。
接下来n行,每行包含m个整数,表示整数矩阵。
接下来q行,每行包含5个整数x1, y1, x2, y2, c,表示一个操作。
输出格式:
共 n 行,每行 m 个整数,表示所有操作进行完毕后的最终矩阵。
数据范围:
1≤n,m≤1000,
1≤q≤100000,
1≤x1≤x2≤n,
1≤y1≤y2≤m,
−1000≤c≤1000,
−1000≤矩阵内元素的值≤1000

输入样例:

3 4 3
1 2 2 1
3 2 2 1
1 1 1 1
1 1 2 2 1
1 3 2 3 2
3 1 3 4 1

输出样例:

2 3 4 1
4 3 4 1
2 2 2 2

解答:

#include <bits/stdc++.h>
using namespace std;
 
const int N = 1010;
int a[N][N] ,S[N][N] = {};
 
int main() {
    int n,m,q;
    cin>>n>>m>>q;
 
    int i, j;
    for (i=1; i<=n; i++) {
        for (j=1; j<=m; j++) {
            cin>>a[i][j];
            S[i][j] = a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1]; 
        }
    }
 
    for (i=0; i<q; i++) {
        int x1, y1, x2, y2, c;
        cin>>x1>>y1>>x2>>y2>>c;
        S[x1][y1] += c;
        S[x1][y2+1] -=c;
        S[x2+1][y1] -=c;
        S[x2+1][y2+1] += c;
    }
 
    for (i=1; i<=n; i++) {
        for (j=1; j<=m; j++) {
            S[i][j] += S[i-1][j]+S[i][j-1]-S[i-1][j-1];
            printf("%d ", S[i][j]);
        }
        cout<<endl;;
    }
 
    return 0;
}

5.双指针

5.1 模板

for (int i = 0, j = 0; i < n; i ++ )
{
    while (j < i && check(i, j)) j ++ ;

    // 具体问题的逻辑
}

核心思想:使用双指针算法是可以把暴利双循环算法优化到O(N)

常见问题分类:
    (1) 对于一个序列,用两个指针维护一段区间
    (2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作

5.2 例题

题目:
给定两个升序排序的有序数组A和B,以及一个目标值x。数组下标从0开始。
请你求出满足A[i] + B[j] = x的数对(i, j)。

数据保证有唯一解。

输入格式:
第一行包含三个整数n,m,x,分别表示A的长度,B的长度以及目标值x。

第二行包含n个整数,表示数组A。

第三行包含m个整数,表示数组B。

输出格式:
共一行,包含两个整数 i 和 j。

数据范围:
数组长度不超过100000。
同一数组内元素各不相同。
1≤数组元素≤10^9

输入样例:

4 5 6
1 2 4 7
3 4 6 8 9

输出样例:

1 1
-----------------------暴力解法------------------------
#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

const int N=100010;
int A[N],B[N];
int l,r;

int main(){
    int n,m,x;
    cin>>n>>m>>x;
    for(int i=0;i<n;i++) 
       cin>>A[i];
            
    for(int i=0;i<m;i++) 
       cin>>B[i];
      
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            if(A[i]+B[j]==x){
                l=i;
                r=j;
            }
        }
    cout<<l<<" "<<r;
    return 0;
}

---------------------双指针-------------------------
#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

const int N=100010;
int A[N],B[N];

int main(){
    int n,m,x;
    cin>>n>>m>>x;
    for(int i=0;i<n;i++) 
       cin>>A[i];
            
    for(int i=0;i<m;i++) 
       cin>>B[i];
      
    for(int i=0,j=m-1;i<n;i++){
        while(j>=0 && A[i]+B[j]>x) j--;
        if(A[i]+B[j]==x)  {
            cout<<i<<" "<<j;
            break;
        }
    }
    
    return 0;
}

6.位运算

6.1 n的第k位

a.先把第k位右移到最后一位

b.和只有最后一位为1的1进行“与”运算

n>>k&&1

6.2 lowbit操作

lowbit(x)=x&-x--------(-x相当于~x+1)

有多少个1,可以采用

while(x){

        x-=lowbit(x);

        sum++;

}

7.离散化

7.1模板

        给出一列数字,在有些情况下,这些数字的值的绝对大小不重要,而相对大小很重要。具体地说,我们将原始数据排序,然后为每个不同的值分配一个整数。这个整数是该值在排序后出现的位置,即离散化后的数值。

        “离散化”就是用数字的相对值替代它们的绝对值。离散化是一种数据处理的技巧,它把分布广而稀疏的数据转换为密集分布,从而能够让算法更快速、更省空间地处理。

假设有一个值域很大(如0≤x≤10^9)但数量很少(如0<n≤10^5)的数列a。离散化步骤如下。

  • 排序。首先需要对数列排序,排序后才能确定相对大小。
  • 离散化。把排序后的数列元素从1开始逐个分配数值,完成离散化。
  • 归位。把离散化后的每个元素放回原始位置,结束。

问题:

(1)a[n]中可能有重复元素    ----去重

(2)如何快速映射,算出a[i]离散化后的值       ----二分

vector<int> alls; // 存储所有待离散化的值
sort(alls.begin(), alls.end()); // 将所有值排序
alls.erase(unique(alls.begin(), alls.end()), alls.end());   // 去掉重复元素

// 二分求出x对应的离散化的值
int find(int x) // 找到第一个大于等于x的位置
{
    int l = 0, r = alls.size() - 1;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (alls[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return r + 1; // 映射到1, 2, ...n
}

 7.2 例题

题目:

假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。
现在,我们首先进行n 次操作,每次操作将某一位置 x上的数加 c。
接下来,进行 m次询问,每个询问包含两个整数 l 和 r ,你需要求出在区间 [ l , r ] 之间的所有数的和。

输入格式:
第一行包含两个整数 n  和 m 。
接下来 n 行,每行包含两个整数 x 和 c 。
再接下来 m行,每行包含两个整数 l 和 r 。

输出格式:
共 m 行,每行输出一个询问中所求的区间内数字和。

数据范围:

输入样例:

3 3
1 2
3 6
7 5
1 3
4 6
7 8

输出样例:

8
0
5
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

typedef pair<int, int> PII;
const int N = 3 * 1e5 + 10;
int a[N], s[N];
vector<int> alls;
vector<PII> add, query;

// 二分查找
int find(int x)
{
	int l = 0, r = alls.size() - 1;
	while (l < r)
	{
		int mid = l + ((r - l) >> 1);
		if (alls[mid] >= x) r = mid;
		else l = mid + 1;
	}
	return l + 1; // 由于S是从1开始的,所以对应映射位置都往前提一位
}
//二分
int find2(int x){ // 用 lower_bound(), 找到第一个大于等于x的位置(其实也是二分)
    return lower_bound((alls.begin(), alls.end()), x)-alls.begin()+1;
}
int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; ++i)
	{
		int x, c;
		cin >> x >> c;
		add.push_back({x, c});
		alls.push_back(x);
	}
	for (int i = 0; i < m; ++i)
	{
		int l, r;
		cin >> l >> r;
		query.push_back({l, r});
		alls.push_back(l);
		alls.push_back(r);
	}
	sort(alls.begin(), alls.end());
	alls.erase(unique(alls.begin(), alls.end()), alls.end());
	for (auto& item : add)
	{
		int x = find(item.first);
		a[x] += item.second;
	}
	for (int i = 1; i <= alls.size(); ++i) s[i] = s[i - 1] + a[i];
	for (auto& item : query)
	{
		int l = find(item.first), r = find(item.second);
		cout << s[r] - s[l - 1] << endl;
	}
	return 0;
}

8.区间合并

8.1 模板

通常区间合并是给定数个区间,想要将有交集的区间合并成一个区间

a.按左端点进行排序

b.进行合并---三种情况(包含、相交、相接)

// 将所有存在交集的区间合并
void merge(vector<PII> &segs)
{
    vector<PII> res;

    sort(segs.begin(), segs.end());

    int st = -2e9, ed = -2e9;
    for (auto seg : segs)
        if (ed < seg.first)
        {
            if (st != -2e9) res.push_back({st, ed});
            st = seg.first, ed = seg.second;
        }
        else ed = max(ed, seg.second);

    if (st != -2e9) res.push_back({st, ed});

    segs = res;
}

8.2 例题

输入样例:

5
1 2
2 4
5 6
7 8
7 9

 输出样例:

3

解答:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N= 1e5+10;
int st[N],ed[N];  //起点和终点 
int n=0;
//成对出现的数据,对组可以返回两个数据 
typedef pair<int,int> PII; //将 pair<int, int> 定义为 PII 类型的别名 
vector<PII> segs; //创建一个存放区间的数组 
	
void merge(vector<PII> &segs)  //合并区间 
{
	vector<PII> res; //这是答案
	
	sort(segs.begin(),segs.end()); //先给所有的区间从小到大排序,pair排序优先排左端点,再右端点
	
	int st=-2e9,ed=-2e9;  //初始的边界,后面用来纪录当前区间的坐标 
	for(auto seg:segs)  //c++11,seg是循环变量,用于依次表示数组segs中的每个元素 
	{
		if(ed<seg.first) //当前区间右端点小于枚举的区间的左端点,说明找到了一个新的区间 
		{
			if(st!=-2e9) res.push_back({st,ed});  //当st不为初始值时,区间放进答案,实际上题目里的数据全部都不为初始值
			st=seg.first,ed=seg.second;  //更新区间
		}
		else  //除此之外的情况都是有交集的 
		{
			ed=max(ed,seg.second);  //把右端点更新成更右的那一个 
		}
	} 
	res.push_back({st,ed}); //把最后的合并区间加入数组
	//这个最后的合并区间是因为一直在更新右端点而没有触发前面的找到新区间的push_back而存在的,或者是最后枚举的区间与当前区间无交集,此时当前区间被更新为枚举的最后一个区间,但是还没有存入数组之中 
	
	segs=res;  //把原来传入的区间数组更新 
}	
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		int l,r;
		cin>>l>>r;   //输入一个区间
		segs.push_back({l,r}); //向容器末尾添加一个元素,把区间放进segs数组中 
	}
	merge(segs);  //区间合并
	cout<<segs.size()<<endl; //最后数组里有多少个区间,就是合并后的区间数量 
	return 0;
	
}

C++ 常用算法 C++ STL的一些常用的算法:遍历、增删改查、拷贝、替换、算术生成、求交集、并集和差集等 阅读详情

相关推荐

阿里天池新闻推荐实战:多路召回策略解析与优化

本文深入解析阿里天池新闻推荐项目中的多路召回策略,包括ItemCF、UserCF、YouTubeDNN等五种召回模型的协同应用与优化技巧。通过实战案例展示如何提升推荐系统效果,特别针对冷启动问题提出创新解决方案,帮助开发者构建高效的新闻推荐系统。

weixin_26918763的博客 415

计算机视觉与OpenCV算法实战(C++/Python双语教学)

课程目的:OpenCV是应用非常广泛的开源视觉处理库,在图像处理、计算机视觉和自动驾驶中有着非常重要的作用。课程设计特色:(课程当前为第一期)1、C++与Python双语教学Python语言是在计算机视觉中应用最多的一种语言,在工作中,深度学习模型的训练基本上都是使用Python语言编写的训练代码。OpenCV在这个过程中用于图像的预处理(例如图像读取、数据增强)和后处理,还可以用于显示处理的结果,功能强大,使用方便。但是在功能的部署的时候,不管是部署在服务端还是PC端,开发语言基本上用的是C++,所以如何有效的使用OpenCV进行模型或者功能的部署尤为重要。C++语言应用的好坏,在面试中可以看出一个面试者的工程实践能力的强弱,两种语言的开发掌握好了可以使工作如虎添翼。2、全模块讲解我出版了一本图书《学习OpenCV4:基于Python的算法实战》,虽然这本书是写的基于Python的算法实战,但是实际上这本书有详细的介绍算法的C++接口,还有一些C++方向的案例,是以Python为主。图书出版的时候就想双语写作,只是限于篇幅没有成行。本课程不仅采用双语教学,更是对C++的每个模块都做讲解,我们知道,很多的书其实只讲imgproc,如果你翻开一本书图像的形态学运算和图像滤波都是作为独立章节讲解的,那么这本书基本上就可以确定是只是讲解了imgproc模块,但是其他的模块在工作中也有很重要的作用。例如:core模块定义了C++的基本数据结构和基本运算(如四则运算);highgui模块是可视化与交互的模块;feature2d是特征点与特征匹配相关算法所在的模块;ml是机器学习相关的模块;dnn是深度学习相关的模块,可以使用OpenCV进行深度学习模型的部署。这些是很多的书和课程都不会讲的。3、讲解细致本课程会从环境搭建开始讲解,环境搭建尤为重要。从我多年的授课经验总结来看,如果只是给了代码,很多的入门用户环境问题处理不好的话,后面的学习很难进行下去,甚至会丧失学习的信心。4、会讲解C++和Python的开发语法问题是入门用户的一大难关,特别是C++语言。大学只是教授了C语言相关的内容,C++很多同学只懂一点皮毛,所以写代码步履维艰,我们在讲解代码的过程中会顺带讲解C++和Python的内容。我们还会讲解编译相关知识,还有库的装载与链接,这些是学校里不会教的,目前也几乎没有课程讲解。5、讲师经验丰富我讲解过C++和OpenCV的多个课程,广受学员好评。我出版过两本图书《深度学习计算机视觉实战》和《学习OpenCV4》,两本书都是细致入微的讲解,主要针对的就是初学者,所以能够很好的处理课程的难易程度。6、讲义准备充分讲义准备的充分细致,标识清楚明确,重点和疑难点突出。

三维重建笔记_光束平差法(Bundle Adjustment, BA)

目录 1 光束平差法(Bundle Adjustment, BA) 1.1 SFM (Structure‐from‐Motion) 定义 问题描述 1.2 重投影误差 (Reprojection Error) 目标函数 1.3 使用 Levenberg‐Marquardt Algorithm 进行优化 问题描述 简化目标函数 参考 Gauss‐Newton Method ...

惊鸿一博 2万+

C/C++ 算法基础

我们以简单程序Hello World为例说明程序的基本框架。此程序在屏幕上输出一行“Hello World!}这段程序包括二个部分:1.#include #include是C语言的保留字,表示要把另一个文件中的内容包含在本文件中。是被包含的文件的文件名。C语言中提供了一些可以被直接拿来使用、能够完成某些特定功能的库函数,分别声明于不同的头文件中。例如:stdio.h中定义了一些与输入输出有关的函数。

纵横千里 捭阖四方 的专栏 1万+

[PCIE5.0] 2.2.8.9 Optimized Buffer Flush/Fill (OBFF) Message

这段文字讲解的是 优化的缓冲区清空/填充(OBFF)消息,它是 PCI Express(PCIe)规范中的一个可选功能,用于向设备报告平台中央资源的状态。简单来说,OBFF 主要帮助设备了解当前平台资源(如缓存或内存)的状态,从而优化数据的处理和传输。这章重点内容如下。

系统固件工程师 538

【YOLO系列】YOLOv12详解:模型结构、损失函数、训练方法及代码实现

本文提出YOLOv12,一种以注意力为中心的实时目标检测框架,通过创新性改进解决传统YOLO模型在精度与速度上的失衡问题。核心贡献包括:1)轻量混合注意力模块(LHA)结合通道与空间注意力,在不增加计算负担下提升特征提取能力;2)区域注意机制与R-ELAN网络优化特征聚合,显著改善小目标检测(AP_S提升8.3%);3)动态多光谱数据增强策略增强模型鲁棒性。实验表明,YOLOv12在COCO等基准上实现SOTA性能,同时保持2.1 TOPS/W的高能效比,适用于边缘设备部署。该工作为实时目标检测提供了新的注

一碗白开水一 1807

c++常见算法

find 查找自定义数据类型 需要重载==private:int num;public:Person(){}//find 查找自定义数据类型 需要重载==if(ret!cout

qq_51691366的博客 6760

如何通过 GitHub Actions 使用 SSH 自动化部署到阿里云 ECS 实例

通过 GitHub Actions 和 SSH 自动化部署,可以显著提高你的开发效率和部署的可靠性。本文介绍了如何生成 SSH 密钥、将公钥添加到阿里云 ECS 实例、将私钥添加到 GitHub Secrets,以及编写 GitHub Actions 工作流来实现自动化部署。希望这篇文章对你有所帮助!

吃面不喝汤的博客 1511

C++算法竞赛篇(一)十道基础题带你掌握C++入门算法知识

本文介绍了C++算法竞赛中8道基础入门题,涵盖输出、数据类型转换、数学运算和时间计算等核心知识点。内容包括:1)打印"Hello,World!";2)字符三角形拼接;3)ASCII码转换;4)数据类型存储空间;5)鸡兔同笼问题;6)带余除法;7)时间差值计算;8)浮点数舍入。通过逐步解析和代码实现,帮助初学者掌握基础算法思维,为后续竞赛打下坚实基础。每道题均附题目链接和代码示例,适合自学或备赛练习。

2402_83322742的博客 2088

五.EtherCAT开发之STM32F407ZGt6+ LAN9253 外置EEPROM配置数据含义

EtherCAT从站简称ESC,ESC在上电过程中,会自动加载EEPROM中前7个字(1word = 2 byte)到ESC寄存器。ESC寄存器总是可以被EtherCAT主站通过EtherCAT总线访问,无论PDI接口寄存器配置什么值。EEPROM存储器中的前7个字,将决定ESC的工作模式。

AIoT深度探索者 | 嵌入式系统架构师 深耕物联网(IoT)与人工智能(AI)融合技术,聚焦​​边缘计算、图像开发、低功耗通信协议​​,致力于智能硬件,关注我获取最新技术文章信息与海量资源~ 3467

14、改进的目标检测与图像去模糊算法研究

本文研究了改进的目标检测与图像去模糊算法。改进的YOLOv5s算法在目标检测中通过添加PSA模块和VoVGSCSP结构,在轻量化模型的同时提高了检测的准确性和速度,适用于电力操作安全穿戴设备检测等场景。XT-GAN结合Transformer和生成对抗网络,在图像去模糊任务中有效解决了传统方法的不足,具有更低的计算复杂度和良好的鲁棒性。两种算法为计算机视觉领域的相关任务提供了更高效、准确的解决方案。

c7d8e的博客 214

C++基础算法排序篇

主要讲解C++算法中所涉及到的两个排序算法,快排和归并。

本科在读,致力于Linux/C++方向的学习,同时涉及数据结构与算法,操作系统,数据库mysql等等 988

如何使用Agent框架来模拟群体智能?

Agent 框架作为人工智能领域的重要工具,可以模拟复杂的群体智能行为,广泛应用于社会科学、经济学和行为学等领域。

335

C++基础算法二分篇

主要讲解二分算法,分别讲解了整数二分和浮点二分

本科在读,致力于Linux/C++方向的学习,同时涉及数据结构与算法,操作系统,数据库mysql等等 1295

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

GitHub上这些C++项目真香

C++ 学习 项目

winniwu的博客 7606

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C++基础算法高精度篇

主要讲解了高精度算法的四种常用的计算

本科在读,致力于Linux/C++方向的学习,同时涉及数据结构与算法,操作系统,数据库mysql等等 1316

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C++基础算法前缀和和差分篇

主要讲解了前缀和和差分算法

本科在读,致力于Linux/C++方向的学习,同时涉及数据结构与算法,操作系统,数据库mysql等等 1930

C++算法设计与分析例题代码(基础篇)

Wild Chicken Programing TANXL C++算法设计与分析例题代码前言一、求1/1!-1/3!+1/5!-1/7!+...+(-1)^(n+1)/(2n-1)! 前言 最近在读清华大学出版社的算法设计与分析(第三版),把书中的例题完成了一下,并记录于此。(随缘更新) 一、求1/1!-1/3!+1/5!-1/7!+…+(-1)^(n+1)/(2n-1)! #include <iostream> using namespace std; int main() { i

TANXL_csdn 4805

C++二分算法 -- 基础篇

知周所众,在C++中有很多有所算法例如:普通遍历、DFS、BFS、二分…在这里面,查找一维有序数组最常用的基本就是二分了学习二分查找不仅是为了查找,还是为了以后得而二分答案做基础铺垫快去A了这道题吧!

我发布的博客,快来抄答案吧 493

语言及算法基础篇 C++语言 C++语言入门 答案合集

语言及算法基础篇 C++语言 C++语言入门 答案合集

陈思宇501的博客 269

c++算法之搜索篇 - BFS与DFS基础

本文介绍了两种基础图搜索算法:广度优先搜索(BFS)和深度优先搜索(DFS)。BFS采用"水波扩散"式搜索,使用队列实现,适合最短路径等问题;DFS则沿着路径深入探索,可用递归或栈实现,适用于拓扑排序等场景。文章详细讲解了两种算法的工作原理、C++实现代码(包括递归和迭代版本)、时间/空间复杂度分析,并通过可视化示例说明执行过程。这些算法在路径查找、网络爬虫、社交网络分析等领域有广泛应用,是计算机科学中的重要基础。

巴巴博一巴巴博一巴巴博一 493

算法基础篇 · 01 模拟(C++ 题解)

本文介绍算法基础中的“模拟”思想,强调按题意逐项实现。通过三道典型题目:多项式输出(处理符号、系数、指数)、蛇形方阵(方向模拟填数)、字符串展开(多参数规则展开),展示如何将复杂逻辑分解为清晰步骤。代码实现注重细节处理,如首项符号、系数1的省略、越界判断、格式输出等。核心在于准确理解题意并忠实翻译为代码,是竞赛中“签到题”的常见类型,虽基础却需严谨思维。

syagain_zsx的博客 221

C++基础算法离散化及区间合并篇

主要讲解了双指针,位运算,离散化以及区间合并。

本科在读,致力于Linux/C++方向的学习,同时涉及数据结构与算法,操作系统,数据库mysql等等 1620

算法基础篇 · 03 枚举(C++ 题解)

6道算法题,最后两道很有难度,对二进制要有一定的了解

syagain_zsx的博客 154

图像算法工程面试所做的准备——C++基础篇

在面试过程中遇到C++相关的问题,有的也是网上搜索的总结,有的贴出原文链接,有的没有贴 1、虚函数和纯虚函数的区别:   答:虚函数:为了重载和多态的需要,在基类中是有实现的,virtual void Eat(){……};所以子类中可以重载也可以不重载基类中的此函数    纯虚函数:就是基类只定义了函数体,没有实现过程,定义方法如: virtual void Eat() = 0; 纯虚函数...

helloworldding的博客 2241

算法基础篇-七种内排序算法C++实现

七种内排序算法,目前只写了代码,原理解析待补充: 1.交换类排序:冒泡、快排; 2.选择类排序:选择、堆排序; 3.插入类排序:直接插入、希尔; 4.归并排序   测试用例: 5 1 2 4 3 -3 10 100 293 123 212 293 434 5 12 439 3   Todo: 原理、复杂度解析与稳定性解析。   #include&lt;iostream&g...

Rick1860的博客 1087
上一篇: 【测试】 性能测试概念篇
Never~ending
博客等级 码龄4年 221粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值