写在开头的话
今天让我们来学习一下字符串的基础算法。
第一节------字符串的回文和翻转
知识点:
(1)回文串(2)翻转字符串
翻转字符串
实现方式
翻转字符串的函数实现:reverseString 方法接受一个字符串作为输入,将其转换为字符数组,然后使用双指针 left 和 right 来交换数组中对应位置的字符,从而实现字符串的翻转。
图示

代码实现
C++代码实现
cpp
#include <iostream>
#include <string>
std::string reverseString(const std::string& str) {
int left = 0;
int right = str.length() - 1;
std::string reversed = str;
while (left < right) {
// 交换左右两端的字符
char temp = reversed[left];
reversed[left] = reversed[right];
reversed[right] = temp;
// 移动指针
left++;
right--;
}
return reversed;
}
int main() {
std::string str;
std::cout << "输入一个字符串:";
std::cin >> str;
std::string reversed = reverseString(str);
std::cout << "翻转后的字符串为:" << reversed << std::endl;
return 0;
}
Java代码实现
java
public class StringReverse {
public static String reverseString(String str) {
char[] charArray = str.toCharArray();
int left = 0;
int right = charArray.length - 1;
while (left < right) {
// 交换左右两端的字符
char temp = charArray[left];
charArray[left] = charArray[right];
charArray[right] = temp;
// 移动指针
left++;
right--;
}
return new String(charArray);
}
public static void main(String[] args) {
java.util.Scanner scanner = new java.util.Scanner(System.in);
System.out.print("输入一个字符串:");
String str = scanner.nextLine();
String reversed = reverseString(str);
System.out.println("翻转后的字符串为:" + reversed);
scanner.close();
}
}
Python代码实现
python
def reverse_string(s):
# 将字符串转换为列表
s_list = list(s)
left, right = 0, len(s_list) - 1
while left < right:
# 交换左右两端的字符
s_list[left], s_list[right] = s_list[right], s_list[left]
# 移动指针
left += 1
right -= 1
# 将列表转换回字符串
return ''.join(s_list)
# 测试
string_input = input("输入一个字符串:")
reversed_string = reverse_string(string_input)
print("翻转后的字符串为:", reversed_string)
运行结果

可以直接使用reverse函数来翻转字符串,在 C++中该函数在algorithm库中,下面是一个实例:

在 Java 中,可以使用 StringBuilder 类的 reverse() 方法来直接翻转字符串。StringBuilder 是可变的字符序列,它的 reverse() 方法会将字符串中的字符顺序颠倒过来。下面是一个示例:

在这个示例中,我们创建了一个 StringBuilder 对象,并将原始字符串传递给它的构造函数。然后调用 reverse() 方法来翻转字符串,并将结果打印输出。
在 Python 中,可以使用字符串的切片操作来直接翻转字符串,即通过[::-1]的方式。下面是一个示例:

在这个示例中,我们定义了一个名为 reverse_string 的函数,它接受一个字符串作为输入,并返回该字符串的翻转结果。在函数中,我们使用切片操作 [::-1] 来直接翻转字符串,然后将结果返回。
回文串
回文串概念
回文串是指正着读和倒着读都相同的字符串。例如,"level"、"radar"和"noon"都是回文串。
判断回文串的办法
-
isPalindrome1通过简单的字符串反转来实现。 -
isPalindrome2通过字符串两端的指针来移动来实现。

isPalindrome3通过遍历字符串实现。

代码实现
C++代码实现
cpp
#include <iostream>
#include <string>
#include <algorithm> // 包含reverse函数
//简单的字符串反转来实现
bool isPalindrome1(const std::string& str) {
std::string reversed = str;
std::reverse(reversed.begin(), reversed.end());
return str == reversed;
}
//简单的字符串指针来实现
bool isPalindrome2(const std::string& str) {
int left = 0;
int right = str.length() - 1;
// 从字符串两端向中间遍历
while (left < right) {
// 如果两端的字符不相等,则不是回文串
if (str[left] != str[right]) {
return false;
}
// 继续向中间移动
left++;
right--;
}
// 如果整个字符串都遍历完毕,说明是回文串
return true;
}
///通过遍历来实现
bool isPalindrome3(const std::string& str) {
int len=str.length();
for(int i=0;i<len/2;i++){
if(str[i]==str[len-1-i])continue;
return false;
}
return true;
}
int main() {
std::string str;
std::cout << "输入一个字符串:";
std::cin >> str;
if (isPalindrome1(str)) {
std::cout << str << " 是一个回文串。" << std::endl;
} else {
std::cout << str << " 不是一个回文串。" << std::endl;
}
return 0;
}
Java代码实现
java
// 简单的字符串指针来实现
public static boolean isPalindrome2(String str) {
int left = 0;
int right = str.length() - 1;
// 从字符串两端向中间遍历
while (left < right) {
// 如果两端的字符不相等,则不是回文串
if (str.charAt(left) != str.charAt(right)) {
return false;
}
// 继续向中间移动
left++;
right--;
}
// 如果整个字符串都遍历完毕,说明是回文串
return true;
}
// 通过遍历来实现
public static boolean isPalindrome3(String str) {
int len = str.length();
for (int i = 0; i < len / 2; i++) {
if (str.charAt(i) != str.charAt(len - 1 - i)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("输入一个字符串:");
String str = scanner.next();
if (isPalindrome1(str)) {
System.out.println(str + " 是一个回文串。");
} else {
System.out.println(str + " 不是一个回文串。");
}
}
Python代码实现
python
# 简单的字符串反转来实现
def is_palindrome_1(s):
return s == s[::-1]
# 简单的字符串指针来实现
def is_palindrome_2(s):
left, right = 0, len(s) - 1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
# 通过遍历来实现
def is_palindrome_3(s):
length = len(s)
for i in range(length // 2):
if s[i] != s[length - 1 - i]:
return False
return True
if __name__ == "__main__":
s = input("输入一个字符串:")
if is_palindrome_1(s):
print(s, "是一个回文串。")
else:
print(s, "不是一个回文串。")
运行结果

简单总结
通过本节,我们学习到了回文串是一种字符串,其正读和反读都相同。学习回文串的过程中,我们会探讨如何判断一个字符串是否为回文,寻找字符串中的最长回文子串,以及利用动态规划等算法来有效地解决这些问题。通过这些学习,我们不仅可以掌握回文串的基本概念和特性,还可以提升我们的字符串处理能力和算法设计水平。
第二节------字符串的转换与简化
知识点:
(1)字符串转换整数(2)简化字符串
字符串转换整数
字符串转化整数是编程中经常遇到的一个问题,尤其是在处理用户输入或者读取文本文件时或者数据分析等情景。
处理方法
-
遍历和计算:一种常见的方法是遍历字符串中的每个字符,并根据字符的 ASCII 码值计算出相应的数字值。
-
处理符号:需要考虑字符串中是否包含符号,比如正负号。通常需要额外的逻辑来处理符号。
-
处理非数字字符:字符串可能包含数字之外的字符,如空格、字母或其他符号。这些字符需要被正确地处理,通常是被忽略或者报错。
-
异常处理:当字符串无法转换为整数时,需要考虑如何处理异常情况。可能的处理方式包括返回错误信息或者默认值。
代码的核心思路主要包括以下几个步骤:
-
处理前导空格:通过循环跳过字符串开头的空格字符,找到第一个非空字符。
-
处理符号 :检查接下来的字符是否为
+或-,用sign来记录符号。如果是-,将符号设置为负数(-1),否则为正数(1)。 -
转换数字 :遍历字符串的后续字符,依次将每个数字字符转换为对应的整数,并累加到
result中。对于每个数字字符,将其转换为整数的方式是s[i] - '0',然后通过result = result * 10 + 当前数字来构建最终的整数。 -
返回结果 :最终返回
result * sign,即考虑符号后的最终整数结果。
关键点
- 通过
isdigit检查字符是否为数字。 - 处理了空格和正负号。
- 不考虑溢出和异常情况,假设输入是有效的数字字符串。
代码实现
C++代码实现
cpp
#include <iostream>
#include <string>
using namespace std;
int string_to_integer(string s) {
int result = 0;
int sign = 1;
int i = 0;
// 处理空格
while (i < s.length() && s[i] == ' ') {
i++;
}
// 处理符号
if (i < s.length() && (s[i] == '+' || s[i] == '-')) {
sign = (s[i] == '-') ? -1 : 1;
i++;
}
// 转化数字字符为整数值
while (i < s.length() && isdigit(s[i])) {
result = result * 10 + (s[i] - '0');
i++;
}
return sign * result;
}
int main() {
cout << string_to_integer("123") << endl; // 输出: 123
cout << string_to_integer("-456") << endl; // 输出: -456
return 0;
}
Java代码实现
java
// 处理空格
while (i < s.length() && s.charAt(i) == ' ') {
i++;
}
// 处理符号
if (i < s.length() && (s.charAt(i) == '+' || s.charAt(i) == '-')) {
sign = (s.charAt(i) == '-') ? -1 : 1;
i++;
}
// 转化数字字符为整数值
while (i < s.length() && Character.isDigit(s.charAt(i))) {
result = result * 10 + (s.charAt(i) - '0');
i++;
}
return sign * result;
}
public static void main(String[] args) {
System.out.println(stringToInteger("123")); // 输出: 123
System.out.println(stringToInteger("-456")); // 输出: -456
}
Python代码实现
python
def string_to_integer(s):
result = 0
sign = 1
i = 0
# 处理空格
while i < len(s) and s[i] == ' ':
i += 1
# 处理符号
if i < len(s) and (s[i] == '+' or s[i] == '-'):
sign = -1 if s[i] == '-' else 1
i += 1
# 转化数字字符为整数值
while i < len(s) and '0' <= s[i] <= '9':
result = result * 10 + (ord(s[i]) - ord('0'))
i += 1
return sign * result
# 示例
print(string_to_integer("123")) # 输出: 123
print(string_to_integer("-456")) # 输出: -456
运行结果

简化字符串
当谈到简化字符串时,我们通常是指对字符串进行一些操作,以减少其长度或复杂性,同时保留其原始含义。这个过程可以涉及移除重复字符、压缩连续重复字符、或者使用简化规则将字符串转换为更简洁的形式。
处理方法
- 移除重复字符:将字符串中重复出现的字符保留一个,并移除其余重复字符。
- 压缩连续重复字符:将连续重复出现的字符压缩成一个字符,并在其后附加重复次数。
- 使用简化规则:根据特定的规则或模式对字符串进行转换,以达到简化的效果。例如,使用正则表达式替换模式匹配的字符串片段。
- 考虑特殊情况:需要考虑处理特殊字符、边界情况和异常情况,以确保简化过程的正确性和鲁棒性。
代码实现
C++代码实现
cpp
#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_set>
using namespace std;
// 移除重复字符
string removeDuplicates(string s) {
string result;
unordered_set<char> seen;
for (char c : s) {
if (!seen.count(c)) {
result.push_back(c);
seen.insert(c);
}
}
return result;
}
// 压缩连续重复字符
string compressString(string s) {
string result;
int count = 1;
for (int i = 1; i <= s.length(); ++i) {
if (i < s.length() && s[i] == s[i - 1]) {
count++;
} else {
result += s[i - 1] + to_string(count);
count = 1;
}
}
return result;
}
int main() {
string s = "aaabbbccc";
cout << "移除重复字符后的字符串:" << removeDuplicates(s) << endl;
cout << "压缩连续重复字符后的字符串:" << compressString(s) << endl;
return 0;
}
Java代码实现
java
import java.util.HashSet;
public class Main {
// 移除重复字符
public static String removeDuplicates(String s) {
StringBuilder result = new StringBuilder();
HashSet<Character> seen = new HashSet<>();
for (char c : s.toCharArray()) {
if (!seen.contains(c)) {
result.append(c);
seen.add(c);
}
}
return result.toString();
}
// 压缩连续重复字符
public static String compressString(String s) {
StringBuilder result = new StringBuilder();
int count = 1;
for (int i = 1; i <= s.length(); i++) {
if (i < s.length() && s.charAt(i) == s.charAt(i - 1)) {
count++;
} else {
result.append(s.charAt(i - 1)).append(count);
count = 1;
}
}
return result.toString();
}
public static void main(String[] args) {
String s = "aaabbbccc";
System.out.println("移除重复字符后的字符串:" + removeDuplicates(s));
System.out.println("压缩连续重复字符后的字符串:" + compressString(s));
}
}
Python代码实现
python
# 移除重复字符
def remove_duplicates(s):
return ''.join(sorted(set(s), key=s.index))
# 压缩连续重复字符
def compress_string(s):
result = ""
count = 1
for i in range(1, len(s)):
if s[i] == s[i - 1]:
count += 1
else:
result += s[i - 1] + str(count)
count = 1
result += s[-1] + str(count)
return result
# 示例
s = "aaabbbccc"
print("移除重复字符后的字符串:", remove_duplicates(s))
print("压缩连续重复字符后的字符串:", compress_string(s))
运行结果

思路讲解
这段代码主要包含两个功能:移除重复字符 和压缩连续重复字符。下面分别讲述这两个功能的代码思路:
1. 移除重复字符 (removeDuplicates 函数)
功能
从输入字符串中移除重复出现的字符,只保留每个字符的第一次出现。
思路
- 定义一个空的字符串
result用来存储结果。 - 使用
unordered_set<char>来记录已经出现过的字符(因为unordered_set查找的时间复杂度是 O(1))。 - 遍历输入字符串中的每个字符
c,如果该字符没有在seen集合中出现过,则将它加入result,并将该字符添加到seen集合中,以便后续字符检查时跳过已经添加过的字符。 - 最终返回移除重复字符后的结果字符串。
流程
- 遍历输入字符串中的每个字符。
- 检查当前字符是否已经在集合中。
- 如果没有出现过,加入结果字符串。
- 返回处理后的字符串。
2. 压缩连续重复字符 (compressString 函数)
功能
将连续出现的相同字符压缩为该字符加上其连续出现的次数。
思路
- 定义一个空的字符串
result来存储压缩后的字符串。 - 使用一个变量
count记录当前连续字符的个数,初始值设为 1。 - 从字符串的第二个字符开始遍历(第一个字符没有需要比较的前驱)。
- 如果当前字符和前一个字符相同,增加
count。 - 如果不同(或者到达字符串末尾),将前一个字符及其出现的次数追加到
result中,并将count重置为 1,继续处理下一个字符。 - 最终返回压缩后的字符串。
流程
- 初始化结果字符串和计数变量。
- 从第二个字符开始遍历,如果当前字符和前一个字符相同,则计数加 1。
- 如果字符不同,或者遍历到了最后一个字符,将前一个字符和计数加入结果字符串。
- 返回压缩后的字符串。
简单总结
本节简单学习了字符串与数字之间的转化,以及简化字符串的相关知识。字符串转化整数和简化字符串是在编程中常见的字符串处理方式,了解其基本步骤和实现方法有助于解决相关的问题。