数据结构——算法之(031)(将字符串中所有小写字母排在大写字母的前面)

本文介绍了一个特殊的字符串处理算法,该算法能够将指定字符移动到字符串头部,并保持其他字符的相对顺序不变,整个过程不使用额外空间。通过双指针技术实现了高效处理。

【申明:本文仅限于自我归纳总结和相互交流,有纰漏还望各位指出。 联系邮箱:Mr_chenping@163.com】

题目:

函数将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移,但不能改变非'*'字符的先后顺序,函数返回串中字符'*'的数量。
题目分析:

1、需要保持非'*'字符的顺序

2、不开辟额外的空间

3、用快慢指针,指向字符串尾巴,快指针指向非‘*’字符串,慢指针指向'*',然后交换指针内容即可

算法实现:

#include <stdio.h>
#include <string.h>

int str_move_char_to_head(char *str, char move_char)
{
	int len = strlen(str);
	char *fast = str + len - 1;
	char *slow = fast;
	char temp;

	while(len--)
	{
		if(*slow != move_char)
		{
			slow--;
			fast = slow;
			continue;
		}
		if(*fast == move_char)
		{
			fast--;
			continue;
		}
		
		{
			temp = *fast;
			*fast-- = *slow;
			*slow-- = temp;
		}
	}
}

int main(int argc, char *argv[])
{
	printf("%s----->", argv[1]);
	str_move_char_to_head(argv[1], '*');
	printf("%s\n", argv[1]);
}


<think>好的,用户现在想了解在C++中将字符串中的小写字母转换为大写字母的方法。根据用户提供的引用内容,已经有一些示例代码,但用户可能希望得到更全面的解答,同时结合他们之前提到的正则表达式方法。 首先,我需要回顾用户之前的对话历史。用户之前询问的是使用正则表达式的方法,但现在他们可能想比较不同的方法,或者寻找更高效的解决方案。用户提供的引用[1]到[5]展示了多种传统方法,比如直接遍历字符串并修改ASCII码,或者使用C++的库函数如toupper。而用户之前的问题中,我回答了一个结合正则表达式的方法,但用户现在可能更倾向于传统方法,因为引用中的例子都是基于遍历和ASCII操作。 接下来,我需要确定用户的需求。他们明确提到要查找使用C++的方法,可能希望了解不同方法的优缺点,或者具体的实现步骤。考虑到引用中的例子都是针对转换小写字母,用户可能需要一个综合的回答,涵盖多种实现方式,并比较它们的效率、适用场景等。 需要注意,用户之前的回答中提到了正则表达式的方法,但引用中的例子都没有使用正则表达式,而是更直接的方法。这可能意味着用户现在希望得到更高效或更常见的解决方案,而不是正则表达式。因此,在回答时,应该优先介绍传统方法,并提到正则表达式方法作为补充,同时指出其效率可能较低。 另外,用户提供的引用[2]提到了统计转换次数,这可能是一个额外的需求,用户可能希望知道如何同时统计转换的字母数量。因此,在回答中可以包含一个统计功能的示例,以覆盖更多用例。 还需要考虑代码的正确性和最佳实践。例如,使用toupper函数比直接减去32更安全,因为后者依赖于ASCII编码,而toupper是可移植的。引用中的一些例子使用了减去32的方法,这可能在某些情况下不够健壮,尤其是当字符编码不是ASCII时。因此,在回答中应该推荐使用toupper,并解释原因。 最后,要确保回答结构清晰,分点列出不同的方法,并提供代码示例,比较它们的优缺点,并给出应用场景的建议。同时,生成的相关问题需要围绕用户可能感兴趣的其他方面,例如性能比较、Unicode处理等。</think>根据C++字符串处理的最佳实践和参考资料,我为您整理三种主流实现方法,并附上性能对比和适用场景分析: ### 一、基础遍历法(时间杂度$O(n)$) ```cpp #include <iostream> #include <string> std::string to_uppercase(std::string str) { for (char &c : str) { // 引用遍历直接修改原字符串 if (c >= 'a' && c <= 'z') c -= 32; // ASCII码差值法 } return str; } ``` ### 二、STL算法优化版(推荐) ```cpp #include <algorithm> #include <cctype> std::string stl_uppercase(std::string str) { std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){ return std::toupper(c); }); // 标准库函数更安全[^2] return str; } ``` ### 三、带统计功能的实现(满足OI需求) ```cpp #include <iostream> using namespace std; int convert_with_count(string &s) { int count = 0; for (auto &c : s) { if (islower(c)) { c = toupper(c); ++count; } } return count; // 返回转换次数[^2] } // 使用示例 int main() { string input; getline(cin, input); int n = convert_with_count(input); cout << input << "\n" << n; } ``` ### 方法对比表 | 方法 | 时间杂度 | 内存占用 | 优点 | 缺点 | |-------------|------------|----------|--------------------------|--------------------| | 基础遍历法 | $O(n)$ | $O(1)$ | 代码直观 | 依赖ASCII码表 | | STL算法版 | $O(n)$ | $O(1)$ | 跨平台安全,可读性强 | 需要C++11支持 | | 带统计功能 | $O(n)$ | $O(1)$ | 满足竞赛题目特殊需求[^5] | 修改原字符串 | ### 注意事项 1. ASCII码差值法(-32)仅适用于纯英文环境,`toupper()`函数可正确处理扩展字符集[^3] 2. 输入带空格字符串时,应使用`getline(cin, str)`代替`cin >> str`[^1] 3. C风格字符串需注意越界问题,推荐使用`std::string`[^4] ### 扩展应用 ```cpp // 实时转换输出(适合大文件处理) void stream_uppercase() { char c; while(cin.get(c)) { cout.put(toupper(c)); } } ``` --相关问题-- 1. 如何实现大小写不敏感的字符串比较? 2. C++中处理Unicode大小写转换需要注意什么? 3. 不同编码格式(ASCII/UTF-8)对大小写转换有何影响? 4. 为什么竞赛代码常用`bits/stdc++.h`头文件?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值