从0开始学算法——第十一天(字符串基础算法)

写在开头的话

今天让我们来学习一下字符串的基础算法。

第一节------字符串的回文和翻转

知识点:

(1)回文串(2)翻转字符串

翻转字符串

实现方式

翻转字符串的函数实现:reverseString 方法接受一个字符串作为输入,将其转换为字符数组,然后使用双指针 leftright 来交换数组中对应位置的字符,从而实现字符串的翻转。

图示

代码实现

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 码值计算出相应的数字值。

  • 处理符号:需要考虑字符串中是否包含符号,比如正负号。通常需要额外的逻辑来处理符号。

  • 处理非数字字符:字符串可能包含数字之外的字符,如空格、字母或其他符号。这些字符需要被正确地处理,通常是被忽略或者报错。

  • 异常处理:当字符串无法转换为整数时,需要考虑如何处理异常情况。可能的处理方式包括返回错误信息或者默认值。

代码的核心思路主要包括以下几个步骤:

  1. 处理前导空格:通过循环跳过字符串开头的空格字符,找到第一个非空字符。

  2. 处理符号 :检查接下来的字符是否为 +-,用 sign 来记录符号。如果是 -,将符号设置为负数(-1),否则为正数(1)。

  3. 转换数字 :遍历字符串的后续字符,依次将每个数字字符转换为对应的整数,并累加到 result 中。对于每个数字字符,将其转换为整数的方式是 s[i] - '0',然后通过 result = result * 10 + 当前数字 来构建最终的整数。

  4. 返回结果 :最终返回 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 集合中,以便后续字符检查时跳过已经添加过的字符。
  • 最终返回移除重复字符后的结果字符串。
流程
  1. 遍历输入字符串中的每个字符。
  2. 检查当前字符是否已经在集合中。
  3. 如果没有出现过,加入结果字符串。
  4. 返回处理后的字符串。
2. 压缩连续重复字符 (compressString 函数)
功能

将连续出现的相同字符压缩为该字符加上其连续出现的次数。

思路
  • 定义一个空的字符串 result 来存储压缩后的字符串。
  • 使用一个变量 count 记录当前连续字符的个数,初始值设为 1。
  • 从字符串的第二个字符开始遍历(第一个字符没有需要比较的前驱)。
  • 如果当前字符和前一个字符相同,增加 count
  • 如果不同(或者到达字符串末尾),将前一个字符及其出现的次数追加到 result 中,并将 count 重置为 1,继续处理下一个字符。
  • 最终返回压缩后的字符串。
流程
  1. 初始化结果字符串和计数变量。
  2. 从第二个字符开始遍历,如果当前字符和前一个字符相同,则计数加 1。
  3. 如果字符不同,或者遍历到了最后一个字符,将前一个字符和计数加入结果字符串。
  4. 返回压缩后的字符串。

简单总结

本节简单学习了字符串与数字之间的转化,以及简化字符串的相关知识。字符串转化整数和简化字符串是在编程中常见的字符串处理方式,了解其基本步骤和实现方法有助于解决相关的问题。

相关推荐
YJlio几秒前
VolumeID 学习笔记(13.10):卷序列号修改与资产标识管理实战
windows·笔记·学习
weixin_440730502 分钟前
java数组整理笔记
java·开发语言·笔记
小龙2 分钟前
【学习笔记】多标签交叉熵损失的原理
笔记·学习·多标签交叉熵损失
Xの哲學17 分钟前
Linux SMP 实现机制深度剖析
linux·服务器·网络·算法·边缘计算
wuk99840 分钟前
使用PCA算法进行故障诊断的MATLAB仿真
算法·matlab
知识分享小能手41 分钟前
Ubuntu入门学习教程,从入门到精通,Ubuntu 22.04的Linux网络配置(14)
linux·学习·ubuntu
额呃呃43 分钟前
二分查找细节理解
数据结构·算法
无尽的罚坐人生1 小时前
hot 100 283. 移动零
数据结构·算法·双指针
永远都不秃头的程序员(互关)1 小时前
C++动态数组实战:从手写到vector优化
c++·算法
手揽回忆怎么睡1 小时前
Streamlit学习实战教程级,一个交互式的机器学习实验平台!
人工智能·学习·机器学习