B2117 整理药名

记录35

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	string s;
  cin>>n;
	while(n--){
		cin>>s;
		if(s[0]>='a'&&s[0]<='z') s[0]-='a'-'A'; 
		for(int i=1;i<s.size();i++){
			if(s[i]>='A'&&s[i]<='Z') s[i]+='a'-'A'; 
		}
		for(int i=0;i<s.size();i++) cout<<s[i];
		cout<<endl;
	}
	return 0;
} 

题目传送门https://www.luogu.com.cn/problem/B2117


突破点

药品名的第一个字符如果是字母要大写,其他字母小写

👉字符大小写转换


思路

  1. 挨个字符串遍历所有的字符
  2. 检查第一个字符的大小写,是小就写变大写
  3. 检查后面的字符,是大写就变小写

代码简析

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	string s;
  cin>>n;
	while(n--){
		cin>>s;
		if(s[0]>='a'&&s[0]<='z') s[0]-='a'-'A'; 
		for(int i=1;i<s.size();i++){
			if(s[i]>='A'&&s[i]<='Z') s[i]+='a'-'A'; 
		}
		for(int i=0;i<s.size();i++) cout<<s[i];
		cout<<endl;
	}
	return 0;
} 

int n;     其中n代表要输入几个字符串

string s;    其中s用来存储每一次输入的字符串

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	string s;
  cin>>n;
	while(n--){
		cin>>s;
		if(s[0]>='a'&&s[0]<='z') s[0]-='a'-'A'; 
		for(int i=1;i<s.size();i++){
			if(s[i]>='A'&&s[i]<='Z') s[i]+='a'-'A'; 
		}
		for(int i=0;i<s.size();i++) cout<<s[i];
		cout<<endl;
	}
	return 0;
} 

s[0]>='a'&&s[0]<='z'     检测第一个字符是不是小写,然后存回去

s[0]-='a'-'A';      小写字母减去小写a,然后得到字母序号,加上A,得到大写序号,然后存回去

for(int i=0;i<s.size();i++) cout<<s[i];  最后输出这个字符


补充

在CSP竞赛中,字符大小写处理是高频操作,以下是常用手段:


1. ASCII码差值运算法(最常用)

利用大小写字母ASCII码固定相差32的特性,直接进行加减运算。

// 大写转小写
char c = 'A';
c = c + 32;  // 或 c += 'a' - 'A'
// 结果: c = 'a'

// 小写转大写
char d = 'b';
d = d - 32;  // 或 d -= 'a' - 'A'
// 结果: d = 'B'

竞赛优势:零函数调用开销,执行速度最快,适合大规模转换。


2. 位运算法(最高效)

利用字母第5位(0x20)的差异,通过位运算实现O(1)转换。

// 大写转小写:置第5位为1
char c = 'A';
c = c | 0x20;  // 结果: 'a'

// 小写转大写:清零第5位
char d = 'b';
d = d & 0xDF;  // 0xDF = 11011111,结果: 'B'

// 大小写互换
char e = 'a';
e = e ^ 0x20;  // 异或运算,结果: 'A'

竞赛优势:比加减法更快,是极致优化首选,但可读性稍差。


3. 标准库函数法(需类型转换)

使用 <cctype> 头文件的 tolower()toupper()

#include <cctype>

char c = 'A';
c = tolower(c);  // 结果为 'a'

char d = 'b';
d = toupper(d);  // 结果为 'B'

// 重要:必须强制转换为char
c = (char)tolower(c);  // CSP中推荐写法,避免隐式转换警告

竞赛注意:这些函数接收int参数并返回int必须显式强制类型转换,否则可能出错。


4. 宏定义法(竞赛标配)

为避免与std::min冲突,通常用大写宏实现。

// 大写转小写
#define TOLOWER(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 32 : (c))

// 小写转大写
#define TOUPPER(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 32 : (c))

// 使用
char c = TOLOWER('A');  // 'a'
char d = TOUPPER('b');  // 'B'

竞赛优势:代码简洁,无函数调用开销,但需注意括号包裹参数防止宏副作用。


5. 条件判断法(仅判断不转换)

当只需判断字符类型而不转换时使用。

char c = 'x';

// 判断是否为小写字母
if (c >= 'a' && c <= 'z') {
    // 小写处理逻辑
}

// 判断是否为大写字母
if (c >= 'A' && c <= 'Z') {
    // 大写处理逻辑
}

竞赛场景:统计字母出现次数、分类处理等题目。


6. 字符串批量处理法

结合循环与上述方法处理整个字符串。

string s = "Hello CSP-J 2024";

// 全转小写(竞赛高频操作)
for (int i = 0; i < s.length(); i++) {
    if (s[i] >= 'A' && s[i] <= 'Z')
        s[i] += 32;  // 或 s[i] |= 0x20
}

// 全转大写
for (int i = 0; i < s.length(); i++) {
    if (s[i] >= 'a' && s[i] <= 'z')
        s[i] -= 32;  // 或 s[i] &= 0xDF
}

竞赛场景:字符串不区分大小写比较、统一格式化输入。


7. CSP竞赛注意事项

注意事项说明
头文件使用<bits/stdc++.h>可自动包含<cctype>,但显式包含更稳妥
性能优先对10^6以上规模数据,优先使用ASCII运算位运算
类型安全使用标准库函数必须加(char)强制转换,否则编译警告
宏的副作用TOUPPER(c++)会错误递增两次,应避免在宏中用自增
数字与字母转换前必须判断c>='A' && c<='Z',防止非字母字符被错误转换
输入输出使用scanf/printf时,%c会读取空白符,需用cin>>c%s

竞赛推荐组合

最优实践:定义快速宏,兼顾速度与可读性。

#include <bits/stdc++.h>
using namespace std;

// 竞赛常用宏定义
#define ISLOWER(c) ((c) >= 'a' && (c) <= 'z')
#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define TOLOWER(c) ((c) + 32)
#define TOUPPER(c) ((c) - 32)

int main() {
    char c;
    cin >> c;
    
    if (ISUPPER(c)) c = TOLOWER(c);  // 大写转小写
    
    cout << c;
    return 0;
}

总结:CSP竞赛中,ASCII码运算法位运算法是主流,配合宏定义可写出既快又安全的代码。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值