【算法与数据结构】递归函数设计技巧

news2024/11/23 22:17:53

数学归纳法

  • step1: 验证P(1)成立
  • step2: 证明如果P(k)成立,那么P(k+1)也成立
  • step3: 联合step1和step2,证明由P(1)->P(n)成立

在这里插入图片描述

例1:

证明: 1 + 3 + . . . + ( 2 n − 1 ) = n 2 1+3+...+(2n-1) = n^2 1+3+...+(2n1)=n2

  1. 证明P(1)成立: P ( 1 ) = 1 = 1 2 P(1) =1 = 1^2 P(1)=1=12成立
  2. 假设 P ( n − 1 ) = ( n − 1 ) 2 P(n-1) = (n-1)^2 P(n1)=(n1)2,
    有: P ( n ) = ( n − 1 ) 2 + ( 2 n − 1 ) = n 2 − 2 n + 1 + ( 2 n − 1 ) = n 2 P(n) = (n-1)^2+(2n-1) = n^2-2n+1+(2n-1) = n^2 P(n)=(n1)2+(2n1)=n22n+1+(2n1)=n2
  3. 证毕

数学归纳法在程序设计中有什么作用?

例2:

如下程序的正确性

int main()
{
    int sum = 0;
    for (int i = 1; i <= 100; i++)
    {
        sum += i;
    }
    std::cout << sum << std::endl;
    std::cin.get();
}
  1. 证明 P ( 1 ) P(1) P(1) 成立:在程序中就是变量的初始化。
  2. 证明如果P(k)成立,那么P(k+1)也成立:未加i之前的sum是P(k), 加了i之后的sum未P(k+1)
  3. 联合step1和step2,证明由 P ( 1 ) → P ( n ) P(1)\to P(n) P(1)P(n)成立: P(n)成立

递归函数设计的三个重要部分

  1. 重要: 给【递归函数】一个明确的语义
  2. 实现边界条件时的程序逻辑
  3. 假设递归函数调用返回结果是正确的,实现本层函数逻辑

例3:递归求阶乘

  1. 重要: 给【递归函数】一个明确的语义:
    f(n)代表n的阶乘, f ( n ) = n ! f(n) = n! f(n)=n!
  2. 实现边界条件时的程序逻辑:
    n = = 1 时, f ( 1 ) = 1 n == 1时, f(1) = 1 n==1时,f(1)=1
  3. 假设递归函数调用返回结果是正确的,实现本层函数逻辑:
    利用 f ( n − 1 ) 的值,计算 f ( n ) = f ( n − 1 ) ∗ n 利用f(n-1)的值,计算f(n) = f(n-1) * n 利用f(n1)的值,计算f(n)=f(n1)n
 int f(n)
 {
     if (n == 1) return 1;
     return f(n-1) * n;
 }

题目讲解

HZOJ-184-路飞吃桃

题目描述

路飞买了一堆桃子不知道个数,第一天吃了一半的桃子,还不过瘾,又多吃了一个。以后他每天吃剩下的桃子的一半还多一个,到 n 天只剩下一个桃子了。路飞想知道一开始买了多少桃子。

输入

输入一个整数 n(2≤n≤30)n(2≤n≤30)。

输出

输出买的桃子的数量。

样例输入1

2

样例输出1

4 = 2*(1+1)

样例输入2

3

样例输出2

10 = 2*(2*(1+1)+1)

数据规模与限定

时间限制:1 s

内存限制:64 M

题目解析

给定路飞吃了n天桃子,求原本桃子的数量

  1. 重要: 给【递归函数】一个明确的语义:
    f(n)代表能吃n天的桃子的数量
  2. 实现边界条件时的程序逻辑:
    n = = 1 时, f ( 1 ) = 1 n == 1时, f(1) = 1 n==1时,f(1)=1
  3. 假设递归函数调用返回结果是正确的,实现本层函数逻辑:
    利用 f ( n − 1 ) 的值,计算 f ( n ) = ( f ( n − 1 ) + 1 ) ∗ 2 利用f(n-1)的值,计算f(n) = (f(n-1) +1)*2 利用f(n1)的值,计算f(n)=(f(n1)+1)2
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;

int f(int n)
{
	if (n == 1) return 1;
	return (f(n - 1) + 1) * 2;
}

int main()
{
	int n;
	cin >> n;
	cout << f(n) << endl;
	
	return 0;
}

HZOJ-186-弹簧版

题目描述

有一个小球掉落在一串连续的弹簧板上,小球落到某一个弹簧板后,会被弹到某一个地点,直到小球被弹到弹簧板以外的地方。

假设有 n个连续的弹簧板,每个弹簧板占一个单位距离,a[i]代表代表第 i个弹簧板会把小球向前弹 a[i]个距离。比如位置 1 的弹簧能让小球前进 2 个距离到达位置 3 。如果小球落到某个弹簧板后,经过一系列弹跳会被弹出弹簧板,那么小球就能从这个弹簧板弹出来。

现在小球掉到了1 号弹簧板上面,那么这个小球会被弹起多少次,才会弹出弹簧板。 1号弹簧板也算一次。

输入

第一个行输入一个 n代表一共有 n(1≤n≤100000)n(1≤n≤100000)个弹簧板。

第二行输入 n​​ 个数字,中间用空格分开。第 i​个数字 a [ i ] ( 0 < a [ i ] ≤ 30 ) a[i](0<a[i]≤30) a[i](0<a[i]30)代表第 i​个弹簧板可以让小球移动的距离。

输出

输出一个整数,表示小球被弹起的次数。

样例输入1

5
2 2 3 1 2

样例输出1

2

样例输入2

5
1 2 3 1 2

样例输出2

4

数据规模与限定

时间限制:1 s

内存限制:64 M

题目解析

  1. 重要: 给【递归函数】一个明确的语义:
    f(i)代表小球从i位置开始,被弹出弹簧版的次数
  2. 实现边界条件时的程序逻辑:
    i > = n 时, f ( i ) = 0 i >= n时, f(i) = 0 i>=n时,f(i)=0
  3. 假设递归函数调用返回结果是正确的,实现本层函数逻辑:
    利用 f ( i + a [ i ] ) 的值,计算 f ( i ) = f ( i + a [ i ] ) + 1 利用f(i + a[i])的值,计算f(i) = f(i + a[i]) + 1 利用f(i+a[i])的值,计算f(i)=f(i+a[i])+1
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;

int f(int i, vector<int>& arr, int n)
{
	if (i >= n) return 0;
	return f(i + arr[i], arr, n) + 1;
}

int main()
{
	int n;
	cin >> n;
	vector<int> arr;   // 读入一个数组
	for (int i = 0, a; i < n; i++)
	{
	    cin >> a;
	    arr.push_back(a);
	}
	cout << f(0, arr, n) << endl;
	
	return 0;
}

HZOJ-235-递归实现指数型枚举

题目描述

​ 从 1−n 这 n 个整数中随机选取任意多个,每种方案里的数从小到大排列,按字典序输出所有可能的选择方案。
指数型枚举:最多枚举n个,并且每一个数字都要大于它前面的数字。
字典序输出:从小到大输出。

输入

​ 输入一个整数 n。(1≤n≤10)

输出

​ 每行一组方案,每组方案中两个数之间用空格分隔。

​ 注意每行最后一个数后没有空格。

样例输入

3

样例输出

1
1 2
1 2 3
1 3
2
2 3
3

样例输入2

4

样例输出2

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

数据规模与约定

​ 时间限制:1 s

​ 内存限制:256 M

​ 100% 的数据保证 1≤n≤10

题目解析

三个小问题需要解决:

  • 如何按照字典序输出? 可以想象成为现在有n个格子需要去填,每个位置都是从小到大去枚举,枚举顺序就是字典序顺序。

  • 如何保证每个位置的数字都大于前面的数字? 在枚举过程中,传入一个变量,这个变量标记了当前位置最小可以取的数字是多少。

  • 如何输出这些结果?

  1. 重要: 给【递归函数】一个明确的语义:
    i i i 代表当前枚举的是第 i i i个位置, j j j代表当前位置最小可以取的数字,n代表当前位置最大可以取的数字,则 f ( i , j , n ) f(i, j, n) f(i,j,n)代表从第 i i i个位置开始向后枚举,并且第 i i i个位置可以选择的最小的数字为 j j j的情况下,可以实现的所有指数型枚举。
  2. 实现边界条件时的程序逻辑:
    j > n 时,返回 j > n时, 返回 j>n时,返回
  3. 假设递归函数调用返回结果是正确的,实现本层函数逻辑:
    f ( i , j , n ) f(i, j, n) f(i,j,n)是一个集合
    (1) 包含当前 i i i位置的最小可以取的数字 j j j+ 从 i + 1 i+1 i+1位置开始向后枚举,并且第 i + 1 i+1 i+1位置可以选择的最小数字为 j + 1 j+1 j+1的集合
    f ( i , j , n ) = j + f ( i + 1 , j + 1 , n ) f(i, j, n) = j + f(i+1, j+1, n) f(i,j,n)=j+f(i+1,j+1,n)
    (2) 包含当前 i i i位置的最小可以取的数字 j + 1 j+1 j+1+ 从 i + 1 i+1 i+1位置开始向后枚举,并且第 i + 1 i+1 i+1位置可以选择的最小数字为 j + 2 j+2 j+2的集合
    f ( i , j , n ) = j + 1 + f ( i + 1 , j + 2 , n ) f(i, j, n) = j +1+ f(i+1, j+2, n) f(i,j,n)=j+1+f(i+1,j+2,n)

    f ( i , j , n ) = n + f ( i + 1 , n + 1 , n ) f(i, j, n) = n + f(i+1, n+1, n) f(i,j,n)=n+f(i+1,n+1,n)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;


int arr[10];  // 用来存储枚举的数字,最大个数为10

void print_one_result(int n)    // 将arr数组中当前枚举得到的结果进行输出
{
    for (int i = 0; i <= n; i++)
    {
        if (i) cout << " ";
        cout << arr[i]; 
    }
    cout << endl;
    return ;
}

void f(int i, int j, int n)
{
	if (j > n) return ;
	for (int k = j; k <= n; k++)
	{
	    arr[i] = k;
	    print_one_result(i);   // 输出当前位置i及之前所枚举的数字
	    f(i+1, k+1, n);
	}
	return ;
}


int main()
{
	int n;
	cin >> n;
	f(0, 1, n);   // 开始枚举,从0位置开始枚举,0位置可以填写的最小数字是1, 最大是n
	
	return 0;
}

HZOJ-236-递归实现组合型枚举

题目描述

​ 从 1−n这 n 个整数中随机选取 m 个,每种方案里的数从小到大排列,按字典序输出所有可能的选择方案。

输入

​ 输入两个整数 n,m。(1≤m≤n≤10)

输出

​ 每行一组方案,每组方案中两个数之间用空格分隔。

​ 注意每行最后一个数后没有空格。

样例输入

3 2

样例输出

1 2
1 3
2 3

样例输入2

5 3

样例输出2

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

数据规模与约定

​ 时间限制:1 s

​ 内存限制:256 M

​ 100% 的数据保证 1≤m≤n≤10

题目解析

三个小问题需要解决:

  • 如何按照字典序输出? 可以想象成为现在有n个格子需要去填,每个位置都是从小到大去枚举,枚举顺序就是字典序顺序。

  • 如何保证每个位置的数字都大于前面的数字? 在枚举过程中,传入一个变量,这个变量标记了当前位置最小可以取的数字是多少。

  • 如何输出这些结果?

  1. 重要: 给【递归函数】一个明确的语义:
    i i i 代表当前枚举的是第 i i i个位置, j j j代表当前位置最小可以取的数字,n代表当前位置最大可以取的数字,m代表最多可以枚举多少位;则 f ( i , j , n , m ) f(i, j, n,m) f(i,j,n,m)代表从第 i i i个位置开始向后枚举,并且第 i i i个位置可以选择的最小的数字为 j j j的情况下,可以实现的所有组合型枚举。
  2. 实现边界条件时的程序逻辑:
    是否选择了足够多数量的数字, i = = m 时,输出,返回 i == m时,输出, 返回 i==m时,输出,返回
  3. 假设递归函数调用返回结果是正确的,实现本层函数逻辑:
    f ( i , j , n , m ) f(i, j, n, m) f(i,j,n,m)是一个集合
    (1) 包含当前 i i i位置的最小可以取的数字 j j j+ 从 i + 1 i+1 i+1位置开始向后枚举,并且第 i + 1 i+1 i+1位置可以选择的最小数字为 j + 1 j+1 j+1的集合
    f ( i , j , n , m ) = j + f ( i + 1 , j + 1 , n , m ) f(i, j, n, m) = j + f(i+1, j+1, n, m) f(i,j,n,m)=j+f(i+1,j+1,n,m)
    (2) 包含当前 i i i位置的最小可以取的数字 j + 1 j+1 j+1+ 从 i + 1 i+1 i+1位置开始向后枚举,并且第 i + 1 i+1 i+1位置可以选择的最小数字为 j + 2 j+2 j+2的集合
    f ( i , j , n , m ) = j + 1 + f ( i + 1 , j + 2 , n , m ) f(i, j, n, m) = j +1+ f(i+1, j+2, n, m) f(i,j,n,m)=j+1+f(i+1,j+2,n,m)

    f ( i , j , n , m ) = n + f ( i + 1 , n + 1 , n , m ) f(i, j, n, m) = n + f(i+1, n+1, n, m) f(i,j,n,m)=n+f(i+1,n+1,n,m)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;


int arr[10];  // 用来存储枚举的数字,最大个数为10

void print_one_result(int m)    // 将arr数组中当前枚举得到的结果进行输出
{
	for (int i = 0; i < m; i++)
	{
		if (i) cout << " ";
		cout << arr[i];
	}
	cout << endl;
	return;
}

void f(int i, int j, int n, int m)
{
	if (i == m)
	{
		print_one_result(m);  // 枚举了m位,是时候输出这m个数字
		return ;               // 输出完结果后就可以返回
	}
	for (int k = j; k <= n && m - i - 1 <= n - k; k++)    // 开始枚举, 加了一个条件,实现剪枝,循环不需要
	{
		arr[i] = k;
		f(i + 1, k + 1, n, m);
	}
	return ;
}


int main()
{
	int n, m;
	cin >> n >> m;
	f(0, 1, n, m);   // 开始枚举,从0位置开始枚举,0位置可以填写的最小数字是1, 最大是n

	return 0;
}

HZOJ-237-递归实现排列型枚举

题目描述

​ 从 1−n这 n个整数排成一排并打乱次序,按字典序输出所有可能的选择方案。
输出全排列。
排列型枚举:后面的数字可以比前面的数字小,当前位置枚举的数字必须是前面位置没用过的数字。

输入

​ 输入一个整数 n。(1≤n≤8)

输出

​ 每行一组方案,每组方案中两个数之间用空格分隔。

​ 注意每行最后一个数后没有空格。

样例输入

3

样例输出

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

数据规模与约定

​ 时间限制:1 s

​ 内存限制:256 M

​ 100% 的数据保证 1≤n≤8

题目解析

三个小问题需要解决:

  • 如何按照字典序输出? 可以想象成为现在有n个格子需要去填,每个位置都是从小到大去枚举,枚举顺序就是字典序顺序。

  • 如何判断当前枚举的数字在之前有没有出现过? 在枚举过程中,传入一个变量,这个变量标记了当前位置最小可以取的数字是多少。

  • 如何输出这些结果?

  1. 重要: 给【递归函数】一个明确的语义:
    i i i 代表当前枚举的是第 i i i个位置,n代表当前位置最大可以取的数字;则 f ( i , n ) f(i, n) f(i,n)代表从第 i i i个位置开始向后枚举,枚举n位的全排列。
  2. 实现边界条件时的程序逻辑:
    i = = n 时,输出,返回 i == n时, 输出,返回 i==n时,输出,返回
  3. 假设递归函数调用返回结果是正确的,实现本层函数逻辑:
    f ( i , n ) f(i, n) f(i,n)是一个集合
    (1) 包含当前 i i i位置之前没有出现过的数字 v [ 0 ] v[0] v[0]+ 从 i + 1 i+1 i+1位置开始向后枚举的全排列
    f ( i , n ) = v [ 0 ] + f ( i + 1 , n ) f(i, n) = v[0] + f(i+1,n) f(i,n)=v[0]+f(i+1,n)
    (2) 包含当前 i i i位置之前没有出现过的数字 v [ 1 ] v[1] v[1]+ 从 i + 1 i+1 i+1位置开始向后枚举的全排列
    f ( i , n ) = v [ 1 ] + f ( i + 1 , n ) f(i, n) = v[1] + f(i+1,n) f(i,n)=v[1]+f(i+1,n)

    f ( i , n ) = v [ n − i ] + f ( i + 1 , n ) f(i, n) = v[n-i] + f(i+1,n) f(i,n)=v[ni]+f(i+1,n)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;


int arr[10], vis[10] = {0};  // arr用来存储枚举的数字,最大个数为10; vis用来存储没有被使用过的数字

void print_one_result(int n)    // 将arr数组中当前枚举得到的结果进行输出
{
	for (int i = 0; i < n; i++)
	{
		if (i) cout << " ";
		cout << arr[i];
	}
	cout << endl;
	return;
}

void f(int i, int n)
{
	if (i == n)
	{
		print_one_result(n);  // 枚举了n位,是时候输出这n个数字
		return ;               // 输出完结果后就可以返回
	}
	for (int k = 1; k <= n; k++)    // 开始枚举, 加了一个条件,实现剪枝,循环不需要
	{
	    if (vis[k]) continue;   // 如果第k位置之前被使用过(vis[k] = 1),则直接跳过
		arr[i] = k;              // k没有被使用过, 把k放在第i位
		vis[k] = 1;              // 同时标记k这个数字已经被使用了
		f(i + 1, n);           // 此时,从第i+1位后面已经枚举完了,返回到当前这层的枚举,也就是说,已经输出了第i个位置等于k的所有结果
		vis[k] = 0;     // 对k进行回收,也就是可以对k重新使用
	}
	return ;
}


int main()
{
	int n;
	cin >> n;
	f(0, n);   // 开始枚举,从0位置开始枚举,n位全排列

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/489908.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Midjourney之logo设计(建议收藏)

目录 宠物诊所的logo设计 常见的Logo类型 图形logo: 字母LOGO APP LOGO 进阶技巧 设置艺术家风格 去掉不需要的元素 ChatGPT Midjourney设计logo 聊天&#xff08;国产&#xff09;&#xff1a;文心一言通义千问 绘图&#xff08;国产&#xff09; UI设计 ChatGP…

LangChain入门(四)-构建本地知识库问答机器人

在这个例子中&#xff0c;我们会介绍如何从我们本地读取多个文档构建知识库&#xff0c;并且使用 Openai API 在知识库中进行搜索并给出答案。 目录 一、安装向量数据库chromadb和tiktoken 二、使用案例 三、embeddings持久化 四、在线的向量数据库Pinecone 一、安装向量数…

Maya云渲染怎么操作?看这一篇就够了

Autodesk Maya 是一款3D动画和视觉效果软件&#xff0c;拥有强大的角色建模、绑定、动画和模拟工具集&#xff0c;与Maya兼容的渲染器包括 Arnold&#xff08;默认渲染器&#xff09;、iRay、Maxwell、ProRender、Octane、Redshift、V-Ray、RenderMan 等。 与 Autodesk 的所有产…

异常排查 | 有关页面部署Tomcat造成的端口冲突问题

今日在写Servlet的时候&#xff0c;将网页部署到tomcat时&#xff0c;出现了如下错误&#x1f447; 严重 [main] org.apache.catalina.core.StandardService.initInternal Failed to initialize connector [Connector[HTTP/1.1-8080]]一开始其实还没有发现这个地方出了问题&…

安装适用于Linux的Windows11子系统(WSL2)

1. 主板BIOS开启虚拟化 开启虚拟化需要在BIOS中进行设置&#xff0c;进入主板BIOS→找到虚拟化设置→开启。 2. 检验是否开启虚拟化 打开Windows命令行&#xff0c;并运行 systeminfo固件中已启用虚拟化为是&#xff0c;代表主板BIOS已经开启虚拟化。 3. 启用Windows功能…

操作系统——内存管理

0.关注博主有更多知识 操作系统入门知识合集 目录 7.1内存管理功能 思考题&#xff1a; 7.2物理内存管理 7.2.1分区内存管理 思考题&#xff1a; 7.2.2分区放置策略 7.2.3内存覆盖技术 7.2.4内存交换技术 7.2.5内存碎片 7.3虚拟内存管理 7.3.1页式虚拟存储管理 思…

安全服务体系建设主体内容

安全服务体系建设总共10类工作内容,每类分若干咨询方案或技术实施方案,同时也是一个长期建设与服务的工作,这些工作都是依据《网络安全等级保护基本要求》、《网络安全等级保护安全设计技术要求》《网络安全等级保护定级指南》。关于如何定级在这篇 等保定级报告模版_luozho…

STM32F4_USMART调试组件

目录 1. USMART是什么&#xff1f; 2. USMART的特点 3. USMART实现流程 4. USMART组件 5. 在usmart_config.c中添加想要被USMART调用的函数 6. 实验程序 6.1 main.c 6.2 usmart.c 6.3 usmart.h 7. USMART调试的优越性说明 1. USMART是什么&#xff1f; USMART 是 AL…

压力测试工具Jmeter安装及使用

1.安装Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量。 1.1.下载 可以Apache Jmeter官网下载&#xff0c;地址&#xff1a;http://jmeter.apache.org/download_jmeter.cgi 1.2.解压 因为下载的是zip包&#xff…

三次样条曲线CubicSpline

本文参考老张在上海轨迹规划 之 三次样条曲线&#xff08;概念性质&#xff09; - 知乎 (zhihu.com) 什么是三次样条曲线 之 三次 样条是一种数据插值的方式&#xff0c;在多项式插值中&#xff0c;多项式是给出的单一公式来尽可能满足所有的数据点&#xff0c;而样条则使用多…

刷题刷题。

租用游艇 1.格式化输入二维数组&#xff1a;1-2&#xff0c;1-3&#xff0c;1-4&#xff0c;2-3&#xff0c;2-4&#xff0c;3-4... ... for(int i1; i<n-1; i) for(int ji1; j<n; j) 2.三重for循环枚举路径&#xff1a;第…

D. Unique Palindromes(回文串/构造)

题目 题意 给定字符串的长度&#xff0c;以及k个条件。 对于每个条件&#xff0c;给定x和c&#xff0c;表示原字符串的长度为x的前缀字符串&#xff0c;存在c个互不相同的回文子串。 原字符串由26个小写字母组成。 构造出长度为n&#xff0c;且满足上述k个条件的字符串。如果…

不黑艺术学社京藏行——参观五台山孙溟㠭为五台山红英师治印

不黑学社社长孙溟㠭先生与五台山菩萨顶主事红英师 不黑学社京藏行&#xff0c;路经五台把佛拜。 巍巍五台清凉境&#xff0c;参访伊始菩萨顶。 感恩“天珠”刘诗语&#xff0c;芬芳佛语满香华。 感恩慈悲红英师&#xff0c;带众参拜大白塔。 菩萨顶上如意宝&#xff0c;莲…

springboot+vue口腔管理平台(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的口腔管理平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌&a…

微服务---分布式多级缓存集群实现方案(Caffeine+redis+nginx本地缓存+Canal数据同步)

分布式多级缓存集群实现方案 1.什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后&#xff0c;先查询Redis&#xff0c;如果未命中则查询数据库&#xff0c;如图&#xff1a; 存在下面的问题&#xff1a; •请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的…

DJ5-1/2 输入输出系统(第一节课)

目录 5.1 I/O 系统的功能、模型和接口 5.1.1 I/O 系统的基本功能 5.1.2 I/O 系统的层次结构和模型 5.1.3 I/O 系统接口 5.2 I/O 设备和设备控制器 5.2.1 I/O 设备 5.2.2 设备控制器 5.2.3 I/O 通道 5.2.4 总线系统 5.1 I/O 系统的功能、模型和接口 5.1.1 …

Python进阶篇(五)-- 邮件客户端实现与电子邮件发送

1 SMTP 通过完成本实验&#xff0c;我们将更加了解SMTP协议。还将学到使用Python实现标准协议的经验。 主要任务是开发一个简单的邮件客户端&#xff0c;将邮件发送给任意收件人。客户端将需要连接到邮件服务器&#xff0c;使用SMTP协议与邮件服务器进行对话&#xff0c;并向邮…

【P5】JMeter HTTP Cookie管理器

文章目录 一、测试网站二、Cookie 设置规则2.1、无配置元件时&#xff0c;Cookie 不会自动设置&#xff08;与线程组设置无关&#xff09;2.2、有配置元件&#xff0c;不选任何参数时&#xff0c;Cookie 自动设置&#xff08;与线程组设置无关&#xff09;2.3、有配置元件&…

【iOS KVO(上)实现过程】

前言 KVO 也适用于传值&#xff0c;在之前的学习只是学习了KVO的传值&#xff0c;今天详细学习 监听和实现 源码放在下一节学习 1.1 KVO KVO&#xff08;Key-Value Observing&#xff09;是Objective-C语言中一种观察者模式的实现&#xff0c;可以用来监听对象属性值的变化…

Kafka基础概念介绍

背景 Kafka是我们项目用的最多的消息中间件&#xff0c;但里面也有很多存在的问题&#xff0c;如重复消费、带宽瓶颈、部分分区消费不下来的异常场景。 重复消费问题有些让人头疼&#xff08;reblance导致offset提交失败&#xff09;&#xff0c;这里会持续更新&#xff08;基…