C++蓝桥杯基础篇(七)
片头
嗨~小伙伴们,大家好!今天我们来一起学习蓝桥杯基础篇(七),学习相关字符串的知识,准备好了吗?咱们开始咯!
一、字符与整数的联系——ASCII码
每个常用字符都对应一个-128~127的数字,二者之间可以相互转化:
int main() {char c = 'a';cout << (int)c << endl;int a = 66;cout << (char)a << endl;return 0;
}
打印结果为:
97
B
常用的ASCII值:'A'~'Z'是65~90,'a'~'z'是97~122,'0'~'9'是48~57,字符可以参与运算,运算时会将其当做整数:
// 字符可以参与运算,运算时会将其当做整数
int main() {int a = 'B' - 'A';int b = 'A' * 'B';char c = 'A' + 2;cout << a << endl;cout << b << endl;cout << c << endl;return 0;
}
运行结果为:
1
4290
C
练习:输入一行字符,统计出其中数字字符的个数,以及字母字符的个数
//练习: 输入一行字符,统计出其中数字字符的个数,以及字母字符的个数
int main() {char c;int num = 0; //数字字符的个数int chars = 0; //字母字符的个数while (cin >> c) {if (c >= '0' && c <= '9') num++;else if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') chars++;}cout << "数字字符的个数为: " << num << endl;cout << "字母字符的个数为: " << chars << endl;return 0;
}
二、字符数组
字符串就是字符数组加上结束符'\0'。
可以使用字符串来初始化字符数组,但是要注意,每个字符串结尾会暗含一个'\0'字符,因此字符数组的长度至少要比字符串的长度多1!
int main() {char a1[] = { 'C','+','+' }; //没有'\0'char a2[] = { 'C','+','+','\0' }; //有'\0'char a3[] = "C++"; //自动添加表示字符串结尾的空字符'\0'//char a4[6] = "Daniel";//没有位置存放'\0',报错char a4[7] = "Daniel"; //正确写法cout << sizeof a1 << endl; //3cout << sizeof a2 << endl; //4cout << sizeof a3 << endl; //4return 0;
}
如果我们想访问从字符数组的第2个位置开始,或者从中间位置开始,那么我们可以这样:
int main() {char a2[] = { 'A','B','C','D','\0' };char a3[] = "ABCDEF";cout << a2 + 1 << endl; //BCDprintf("%s\n", a3 + 2); //CDEFreturn 0;
}
2.1 字符数组的输入输出
// 2.1 字符数组的输入输出int main() {char str[100];char s[100];scanf("%s", s); //这里不能加&,数组名代表首元素的地址cin >> str; //输入字符串时,遇到空格或者回车就会停止cout << str << endl; //输出字符串时,遇到空格或者回车不会停止printf("%s\n", str);return 0;
}
读入一行字符串,包括空格
//读入一行字符串,包括空格
int main8() {char str[100];gets(str); cout << str << endl;return 0;
}
虽然用 gets() 时有空格也可以直接输入,但是 gets() 有一个非常大的缺陷,即它不检查预留存储区是否能够容纳实际输入的数据。
换句话说,如果输入的字符数目大于数组的长度,gets 无法检测到这个问题,就会发生内存越界,所以编程时建议使用 fgets()。
fgets()函数原型为:
char *fgets(char *s, int size, FILE *stream);
从stream流中读取size个字符存储到字符指针变量s所指向的内存空间
返回值为一个指针,指向字符串中第一个字符的地址
1. s:代表要保存到内存空间的首地址,可以是字符数组名,也可以是指向字符数组的字符指针变量名
2. size:代表的是读取字符串的长度
3. stream:表示从何种流中读取,可以是标准输入流stdin,也可以是文件流
因此,我们可以使用fgets()来帮助我们读取字符串
int main() {char str[100];//从输入流stdin中最多读取100个字符到字符数组str中。//除去末尾的字符串结束符,实际上最多读取99个字符//fgets函数可以读取到空格和'\n'fgets(str, 100, stdin);cout << str << endl;return 0;
}
我们还可以使用cin来读取string类型的字符串,cin输入接触到第一个非空格字符时开始阅读,当遇到下一个字符(空格、制表符、换行符)时,就会停止读取
int main() {string s;printf("输入:\n");cin >> s;printf("输出:\n");cout << s;return 0;
}
为了避免cin对于空白符的忽略问题,我们可以使用getline函数,getline函数可以读取整行,包括前面和中间的空格,并将其存储在字符串对象中,在输入时,直至遇到'\n'或EOF,才终止一行字符串的输入操作。
getline()函数有4种重载形式,这里我们先介绍1种,后续慢慢讲解
istream& getline(istream& is, string& str);
读取的istream是作为参数 is 传进函数的,读取的字符串保存在string类型的str中。
is : 表示一个输入流,例如cin。
str : 为string类型的引用,用来存储输入流中的流信息。
因此,我们可以使用getline()函数来读取字符串
int main() {string s;getline(cin, s);cout << s << endl;return 0;
}
2.2 字符数组的常用操作
下面几个函数需要引入头文件 #include<string.h>
(1)strlen(str),求字符串的长度
(2)strcmp(a,b),比较2个字符串的大小,a<b返回-1,a==b返回0,a>b返回1。这里的比较方式就是字典序!
(3)strcpy(a,b),将字符串b复制给从a开始的字符数组
下面我们依次来介绍这些函数
①strlen(str),求字符串的长度
// (1)strlen(str),求字符串的长度
int main() {char a[100] = "hello world!";cout << strlen(a) << endl; // 12return 0;
}
②strcmp(a,b),比较2个字符串的大小
// (2)strcmp(a,b),比较2个字符串的大小,
// a<b时,返回-1;a==b时,返回0;a>b时,返回1int main() {char s1[100], s2[100];scanf("%s%s", s1, s2); //scanf函数的%s,会自动忽略空格,换行,Tab键cout << strcmp(s1, s2) << endl;return 0;
}
或者
int main() {char s1[100];scanf("%s", s1);cout << strcmp(s1, "abc") << endl;//将s1字符数组里面的内容和"abc"进行比较return 0;
}
③strcpy(a,b),将字符串b复制给从a开始的字符数组
// (3)strcpy(a,b),将字符串b复制给从a开始的字符数组
int main() {char s1[100], s2[100];scanf("%s", s1);strcpy(s2, s1);cout << s2 << endl;return 0;
}
2.3 遍历字符数组中的字符
遍历数组,当然采用for循环了,while循环也可以
//2.3 遍历字符数组中的字符int main() {char a[100] = "hello world!";for (int i = 0; i < strlen(a); i++) {cout << a[i] << endl;}return 0;
}
这种方法行是行,但是每次都要计算strlen(a),花费了很多时间,有没有更省时的方法?
肯定有!把strlen(a)的结果存放在临时变量里面不就可以了~
int main() {char s1[100];scanf("%s", s1);for (int i = 0, len = strlen(s1); i < len; i++) //将strlen(s1)的结果保存到len中{cout << s1[i] << endl;}return 0;
}
当然了,我们还可以在外面写:
int main() {char s1[100];scanf("%s", s1);int len = strlen(s1);for (int i = 0; i < len; i++) {cout << s1[i] << endl;}return 0;
}
练习1:只出现1次的字符
给定一个只包含小写字母的字符串,请你找出第一个仅出现一次的字符。如果没有,输出"no"。
思路:
①我们可以先定义str数组,用来读取输入的字符串,str数组长度可能会很大很大,所以定义为全局变量。
②再定义num数组,用来统计每个字母出现的次数,字母总数26个,因此,num数组长度为26。下标从0~25.,下标为0表示'a'出现的次数,下标为1表示'b'出现的次数....(相当于num数组是26个字母的映射)
③如何统计每个字母出现的次数呢?很简单,’a'的ASCII码值为97,对应num数组下标为0的位置,'a'出现的次数 = num数组下标为0位置的值;每当'a'出现1次,num[0]++;所以,表达式应为 num[str[i]-'a']
④当num数组出现任一下标的值为1的情况,即num[str[i]-'a'] == 1时,就是仅出现一次的字符。我们只需输出这个字符即可,即str[i],并且终止循环。
⑤如果num数组没有上面④这种情况,输出"no"
本道题代码如下:
//练习1:给定一个只包含小写字母的字符串,
//请找出第一个仅出现1次的字符。
//如果没有,输出"no"int num[26] = { 0 };
char str[10010];int main() {cin >> str;int len = strlen(str);for (int i = 0; i < len; i++) {num[str[i] - 'a']++;}for (int i = 0; i < len; i++) {if (num[str[i] - 'a'] == 1) {cout << str[i] << endl;return 0; //直接main函数结束,无需执行后续代码}}cout<<"no"<<endl;//如果没找到,输出"no"return 0;
}
第二个for循环也可以这样写:
for (int j = 0; j < 26; j++) {if (num[j] == 1) //如果num数组对应下标位置的值为1{cout << char(j + 'a') << endl;//输出该字符,强转成char类型return 0;}}
练习2:替换字符
把一个字符串中特定的字符全部用给定的字符替换,得到一个新的字符串
这道题,比较简单。代码如下:
//练习2:把一个字符串中特定的字符全部用给定的字符替换
//得到一个新的字符串int main() {char str[31] = { 0 };scanf("%s", str); //scanf函数的%s,会自动忽略空格,换行,Tab键char c;scanf("\n%c", &c); //scanf函数的%c,任何数据都会被当作一个字符//不管是数字还是空格、回车、Tab键它都会取回for (int i = 0; str[i]; i++) {if (str[i] == c) {str[i] = '#';}}puts(str);return 0;
}
也可以使用下面这种方法:
int main() {char str[31] = { 0 };cin >> str; //用cin也可以int len = strlen(str);//strlen函数的参数类型是char*char c;cin >> c;for (int i = 0; i < len; i++) {if (str[i] == c) {str[i] = '#';}}cout << str << endl; //使用cout也可以return 0;
}
三、标准库类型 string
可变长的字符序列,比字符数组更加好用,需要引入头文件:#include<string>
3.1 定义和初始化
//3.1 定义和初始化
int main() {string s1; //默认初始化,s1是一个空字符串string s2 = s1; //s2是s1的副本string s3 = "hiya"; //s3是该字符串字面值的副本string s4(10, 'c'); //s4的内容是 ccccccccccreturn 0;
}
3.2 string上的操作
(1)string的读写
//3.2 string上的操作
//(1)string的读写int main() {string s1, s2;cin >> s1 >> s2;cout << s1 << s2 << endl;return 0;
}
注意:不能用printf直接输出string,需要写成:printf("%s",s.c_str());
(2)使用getline读取一整行
//(2)使用getline读取一整行int main() {string s;getline(cin, s);cout << s << endl;return 0;
}
(3)string 的 empty 和 size 操作(注意 size 是无符号整数,因此 s.size() <= -1 一定成立):
//(3)string的empty和size操作(注意:size是无符号整数,因此s.size()<=-1一定成立):int main() {string s1, s2 = "abc";cout << s1.empty() << endl; // 1cout << s2.empty() << endl; // 0cout << s2.size() << endl; // 3return 0;
}
(4)string 的比较
支持 > < >= <= == != 等所有比较操作,按字典序进行比较
(5)为string对象赋值:
int main() {string s1(10, 'c'), s2; //s1 的内容是cccccccccc;s2是一个空字符串s1 = s2; //赋值:用s2的副本替换s1的副本//此时s1和s2都是空字符串return 0;
}
(6)两个string对象相加:
//2个string对象相加int main() {string s1 = "abc", s2 = "def";string s3 = s1 + s2; //abcdefs3 += s1 + s2; //abcdefabcdefcout << s3 << endl;return 0;
}
(7)字面值和string对象相加:
做加法运算时,字面值和字符都会被转化成string对象,因此直接相加就是将这些字面值串联起来:
string s1 = "hello", s2 = "world";string s3 = s1 + "," + s2 + '!';cout << s3 << endl; //hello,world!
当把string对象和字符字面值及字符串字面值混再一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string:
string s4 = s1 + ","; //正确: 把一个string对象和有一个字面值相加//string s5 = "hello" + ","; //错误: 两个运算对象都不是string,//本质上是2个const char*类型的指针相加//2个都是字符串常量,肯定是不能改变,不能进行相加string s6 = s1 + "," + "world"; //正确: 每个加法运算都有一个运算符是string//如果从左到右,有一个string类型的,后面才会隐式类型转换//string s7 = "hello" + "," + s2; //错误: 不能把字面值直接相加,运算是从左到右进行的//从左到右,先是"hello"+","相加,所以不会有隐式类型转换
3.3 处理string对象中的字符
可以将string对象当成字符数组来处理
//3.3 处理string对象中的字符
//可以将string对象当成字符数组来处理int main() {string s = "hello world";for (int i = 0; i < s.size(); i++) {cout << s[i] << " ";}cout << endl;return 0;
}
或者使用基于范围的for语句
int main() {string s = "hello world";//范围for//把字符串s里面的值依次赋给efor (auto e : s) {cout << e << " ";}cout << endl;return 0;
}
如果我们想改变字符串s里面的值,需要在范围for里面传递引用&
int main() {string s = "hello world";for (char& c : s) {c = 'a';}cout << s << endl; //aaaaaaaaaaareturn 0;
}
练习3:信息加密
密码翻译,输入一个只包含小写字母的字符串,将其中的每个字母替换成它的后继字母,如果原字母是'z',则替换成'a'
emmm,咱们还是来画个图~
OK啦!本道题的代码如下:
//信息加密
int main() {string s;getline(cin, s); //如果用cin,遇到空格,会停止读取//使用getline函数,读取一整行int len = s.size(); //求字符串的长度for (int i = 0; i < len; i++) {if (s[i] >= 'a' && s[i] <= 'z') {s[i] = 'a' + (s[i] - 'a' + 1) % 26;}else if (s[i] >= 'A' && s[i] <= 'Z') {s[i] = 'A' + (s[i] - 'A' + 1) % 26;}}cout << s << endl;return 0;
}
我们还可以使用范围for来优化代码:
int main() {string s;getline(cin, s); //如果用cin,遇到空格,会停止读取//使用getline函数,读取一整行//这里要修改字符串s里面的值,必须传引用&for (auto& e : s) {if (e >= 'a' && e <= 'z') {e = 'a' + (e - 'a' + 1) % 26;}else if (e >= 'A' && e <= 'Z') {e = 'A' + (e - 'A' + 1) % 26;}}cout << s << endl;return 0;
}
练习4:字符串长度
其实这道题,就相当于让我们模拟实现strlen函数。
代码如下:
//求字符串长度
int main() {char s1[100] = { 0 };fgets(s1, 100, stdin);//只能用fgets函数,从标准库中最多读取100个字符存入s1中;直到遇见'\n'为止//并且fgets函数会读取空格和'\n'//scanf("%s", s1); //不能用scanf函数,因为scanf遇到空格或者换行,停止读取//cin >> s1; //不能用cin,因为cin遇到空格或者换行,停止读取int len = 0;//当元素值不是'\0'并且不是'\n',才计入字符串的长度for (int i = 0; s1[i] != '\0' && s1[i] != '\n'; i++) {len++;}cout << len << endl; //没有加上s1[i] != '\n'的判断条件时,写成 cout << len-1 << endl; 也可以return 0;
}
方法二:
int main() {string str;getline(cin, str); //使用getline函数读取一整行cout << str.size() << endl;//调用size()函数return 0;
}
片尾
今天我们学习了字符串相关知识点,希望这篇文章对友友们有所帮助!!!
求点赞收藏加关注!!!
谢谢大家!!!
相关文章:

C++蓝桥杯基础篇(七)
片头 嗨~小伙伴们,大家好!今天我们来一起学习蓝桥杯基础篇(七),学习相关字符串的知识,准备好了吗?咱们开始咯! 一、字符与整数的联系——ASCII码 每个常用字符都对应一个-128~127的…...

8.路由原理专题
路由器数据转发原理,路由表、FIB、快速转发表的关系 路由的控制平面与转发平面 控制平面:负责路由计算,维护;路由协议运行在控制平面 转发平面:进行数据包的封装,报文转发,路由表,FIB表,快速转发表等 控制平面与转发平面相互独立又协同工作 路由器检查数据包的目…...
jQuery UI 简介
jQuery UI 简介 引言 随着互联网技术的飞速发展,前端开发已经成为网站和应用程序建设的重要组成部分。jQuery UI 是一个基于 jQuery 的用户界面库,它为开发者提供了丰富的交互组件和视觉效果,使得创建具有吸引力和互动性的网页变得更加简单。本文将为您详细介绍 jQuery UI…...

Web服务器配置
配置虚拟主机 通过虚拟主机,可以实现用自定义的域名来访问,并且可以为不同的域名指定不同的站点目录。 配置IP地址和域名的映射关系 申请真实的域名需要一定的费用,为了方便开发,可以通过修改hosts文件来实现将任意域名解析到本…...

LINUX网络基础 [一] - 初识网络,理解网络协议
目录 前言 一. 计算机网络背景 1.1 发展历程 1.1.1 独立模式 1.1.2 网络互联 1.1.3 局域网LAN 1.1.4 广域网WAN 1.2 总结 二. "协议" 2.1 什么是协议 2.2 网络协议的理解 2.3 网络协议的分层结构 三. OSI七层模型(理论标准) …...
定制化开发的WooCommerce独立站商城更安全
定制化开发的WooCommerce独立站商城在安全性、交易风险控制以及整体用户体验方面有显著优势。以下是定制化开发在这些方面的具体表现: 1. 安全性更高 定制化开发允许开发者从底层架构开始设计和优化,确保网站的安全性。以下是具体表现: (1…...
Xcode 运行真机失败
错误提示: iPhone xxx is not available because it is unpaired. Pair with the device in the Xcode Devices Window, and respond to any pairing prompts on the device. 处理方法: 把Xcode关闭,手机断开数据线,打开终端&…...

【FFmpeg之如何新增一个硬件解码器】
FFmpeg之如何新增一个硬件解码器 前言一、config配置二、解码器定义1.目录结构2.数据结构 三、解码流程1、初始化mediacodec_decode_init2、帧接收mediacodec_receive_frame2.1 解码上下文MediaCodecH264DecContext2.2 发包AVPacket到解码器 -- ff_mediacodec_dec_send2.3 接收…...

P3385 【模板】负环
P3385 【模板】负环 - 洛谷 题目描述 给定一个 n 个点的有向图,请求出图中是否存在从顶点 1 出发能到达的负环。 负环的定义是:一条边权之和为负数的回路。 输入格式 本题单测试点有多组测试数据。 输入的第一行是一个整数 T,表示测试数…...

破解透明物体抓取难题,地瓜机器人CASIA 推出几何和语义融合的单目抓取方案|ICRA 2025
概述 近日,全球机器人领域顶会ICRA 2025(IEEE机器人与自动化国际会议)公布论文录用结果,地瓜机器人主导研发的DOSOD开放词汇目标检测算法与MODEST单目透明物体抓取算法成功入选。前者通过动态语义理解框架提升复杂场景识别准确率…...

深度学习编译器(整理某survey)
一、深度学习框架 TensorFlow PyTorch MXNet ONNX:定义了一个统一的表示,DL models的格式方便不同框架之间的转换模型 二、深度学习硬件 通用硬件(CPU、GPU):通过硬件和软件优化支持深度学习工作负载 GPU:通过多核架构实现高…...

【计算机网络入门】应用层
目录 1.网络应用模型 1.1 C/S模型(客户端服务器模型) 1.2 P2P模型(对等模型) 2. DNS系统 2.1 域名 2.2 域名解析流程 3. FTP文件传输协议 4. 电子邮件系统 4.1 SMTP协议 4.2 pop3协议 4.3 IMAP协议 4.4 基于万维网的电…...

@PostConstruct注解的作用
PostConstruct 注解功能是在一个类的所有依赖被注入完成后,才会被执行的方法。这种方法通常用于类的初始化,初始化过程中可以进行一些资源加载、连接建立、或其他必要的配置工作。PostConstruct 方法仅被调用一次,通常修饰符是public或者prot…...

HTML + CSS 题目
1.说说你对盒子模型的理解? 一、是什么 对一个文档进行布局的时候,浏览器渲染引擎会根据标准之一的css基础盒模型,将所有元素表示为一个个矩形的盒子。 一个盒子由四个部分组成: content,padding,border,margin 下…...

通过多线程获取RV1126的AAC码流
目录 一RV1126多线程获取音频编码AAC码流的流程 1.1AI模块的初始化并使能 1.2AENC模块的初始化 1.3绑定AI模块和AENC模块 1.4多线程获取每一帧AAC码流 1.5每个AAC码流添加ADTSHeader头部 1.6写入具体每一帧AAC的…...

sql sqlserver的进程资源查看,杀掉多余进程
主要是由三个表组成 sys.sysprocesses、sys.dm_exec_sessions、sys.dm_exec_requests 后面两个在2008版本后使用,主要使用sys.dm_exec_sessions SELECT spid AS 会话ID, -- 进程(会话)的ID blocked AS 被阻塞的会话…...
自然语言处理:朴素贝叶斯
介绍 大家好,博主又来和大家分享自然语言处理领域的知识了。按照博主的分享规划,本次分享的核心主题本应是自然语言处理中的文本分类。然而,在对分享内容进行细致梳理时,我察觉到其中包含几个至关重要的知识点,即朴素…...
Pytorch实现之LSRGAN,轻量化SRGAN超分辨率SAR
简介 简介:在SRGAN的基础上设计了一个轻量化的SRGAN模型结构,通过DSConv+CA与残差结构的设计来减少参数量,同时利用SeLU激活函数构造。与多类SRGAN改进不同的是,很少使用BN层。 论文题目:Lightweight Super-Resolution Generative Adversarial Network for SAR Images(…...

学习记录-缺陷
目录 一、缺陷的判定标准 二、缺陷产生的原因 三、缺陷的生存周期 四、软件缺陷描述及提交要素 1.缺陷的核心内容 2.缺陷的提交要素 五、软件缺陷类型 一、缺陷的判定标准 二、缺陷产生的原因 三、缺陷的生存周期 注入bug > 发现bug > 清除bug 四、软件缺陷描述及提…...

文件压缩与解压工具7-Zip的安装和使用(免费)
一.介绍 7-Zip 是一款开源的文件压缩与解压缩工具,支持多种压缩格式,如 7z、ZIP、RAR、TAR 等。它具有高压缩比,尤其是其独有的 7z 格式,并集成了文件管理器。7-Zip 适用于 Windows 系统,提供命令行版本,…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...