从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. 返回压缩后的字符串。

简单总结

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

相关推荐
嵌入式小能手7 小时前
飞凌嵌入式ElfBoard-系统信息与资源之休眠
c语言·开发语言·算法
鄭郑7 小时前
【Playwright学习笔记 07】其它用户视觉定位的方法
笔记·学习
LYS_06187 小时前
寒假学习(5)(C语言5+模数电5)
c语言·学习·模数电
历程里程碑8 小时前
哈希3 : 最长连续序列
java·数据结构·c++·python·算法·leetcode·tornado
闻缺陷则喜何志丹8 小时前
【图论】P9661 [ICPC 2021 Macao R] Sandpile on Clique|普及+
c++·算法·图论·洛谷
火云洞红孩儿8 小时前
2026年,用PyMe可视化编程重塑Python学习
开发语言·python·学习
2401_841495648 小时前
【LeetCode刷题】两两交换链表中的节点
数据结构·python·算法·leetcode·链表·指针·迭代法
栗少8 小时前
英语逻辑词
学习
傻啦嘿哟8 小时前
构建命令行单词记忆工具:JSON词库与复习算法的完美结合
算法·json
mjhcsp8 小时前
一种新的LCA算法
算法