数据结构和算法

DSA 主页 DSA 概述 DSA 环境设置 DSA 算法基础 DSA 渐近分析

数据结构

DSA 数据结构基础 DSA 数据结构和类型 DSA 数组数据结构

链接列表

DSA 链接列表数据结构 DSA 双向链接列表数据结构 DSA 循环链表数据结构

堆栈 &队列

DSA 堆栈数据结构 DSA 表达式解析 DSA 队列数据结构

搜索算法

DSA 搜索算法 DSA 线性搜索算法 DSA 二分搜索算法 DSA 插值搜索 DSA 跳跃搜索算法 DSA 指数搜索 DSA 斐波那契搜索 DSA 子列表搜索 DSA 哈希表

排序算法

DSA 排序算法 DSA 冒泡排序算法 DSA 插入排序算法 DSA 选择排序算法 DSA 归并排序算法 DSA 希尔排序算法 DSA 堆排序 DSA 桶排序算法 DSA 计数排序算法 DSA 基数排序算法 DSA 快速排序算法

图形数据结构

DSA 图形数据结构 DSA 深度优先遍历 DSA 广度优先遍历 DSA 生成树

树数据结构

DSA 树数据结构 DSA 树遍历 DSA 二叉搜索树 DSA AVL 树 DSA 红黑树 DSA B树 DSA B+ 树 DSA 伸展树 DSA 尝试 DSA 堆数据结构

递归

DSA 递归算法 DSA 使用递归的汉诺塔 DSA 使用递归的斐波那契数列

分而治之

DSA 分而治之 DSA 最大最小问题 DSA 施特拉森矩阵乘法 DSA Karatsuba 算法

贪婪算法

DSA 贪婪算法 DSA 旅行商问题(贪婪方法) DSA Prim 最小生成树 DSA Kruskal 最小生成树 DSA Dijkstra 最短路径算法 DSA 地图着色算法 DSA 分数背包问题 DSA 作业排序截止日期 DSA 最佳合并模式算法

动态规划

DSA 动态规划 DSA 矩阵链乘法 DSA Floyd Warshall 算法 DSA 0-1 背包问题 DSA 最长公共子序列算法 DSA 旅行商问题(动态方法)

近似算法

DSA 近似算法 DSA 顶点覆盖算法 DSA 集合覆盖问题 DSA 旅行商问题(近似方法)

随机算法

DSA 随机算法 DSA 随机快速排序算法 DSA Karger 最小割算法 DSA Fisher-Yates 洗牌算法

DSA 有用资源

DSA 问答 DSA 快速指南


数据结构中的字符串

什么是字符串?

字符串是一种存储字符序列的原始数据结构。它通常用于存储、操作和处理文本,例如用户输入、消息、标签等。每种编程语言都有一套独特的字符串表示规则。例如,在Java中,字符串被视为对象,而在C中,它表示为一个 char 数据类型的数组。在下图中,我们可以看到一个字符串 −

String

在本教程中,我们将探讨字符串的一些属性和操作,以及它们在不同编程语言中的实现方式。

语法

在 C 语言中创建字符串的语法 −

char string_name[string_size] = {单引号内用逗号分隔的字符};
或者,
char string_name[string_size] = "双引号内的字符串";

除了上述语法之外,C++ 还提供了另一种创建字符串的方法 −

string string_name = "双引号内的字符串";

使用 Java 编程语言创建字符串 −

String string_name = "双引号中的字符串";
或者,
String string_name = new String("values");

使用 Python 编程语言创建字符串 −

string_name = "双引号中的字符串"

字符串的必要性

字符串是应用程序与用户之间交互最简单、最理想的方式。它们基于人类可读的字符,易于理解和使用。此外,它们还用于存储各种数据,例如文本、数字、符号、二进制、十六进制等。

字符串表示

与数组类似,字符串也表示为存储桶的集合,每个存储桶存储一个字符。这些存储桶的索引从"0"到"n-1",其中 n 是该特定字符串的长度。例如,一个长度为 10 的字符串,其存储桶的索引为 0 到 9。下图展示了字符串的表示方式 −

字符串表示

以下是上述表示中的一些要点。

  • 索引始终从 0 开始。

  • 如果索引从 0 到 9,则表示该字符串有 10 个元素。

  • 每个字符都可以通过其索引访问。

字符串的基本操作

可以对字符串执行许多操作,例如搜索、拆分、修剪、索引等等。每种编程语言都有自己的一套内置函数或方法,可以帮助轻松执行这些操作。

以下是可以对给定字符串执行的基本操作 −

  • 连接 − 将两个或多个字符串连接在一起。
  • 长度 − 打印字符串中的字符数。
  • 子字符串 − 查找更大字符串的一部分。
  • 反转 − 以相反的顺序打印字符串中的字符。
  • 索引 − 使用索引访问特定字符。

连接操作

连接操作是将两个或多个字符串连接在一起形成一个新字符串的过程。例如,连接两个字符串"Tutorials"和"Point"将得到"TutorialsPoint"。根据编程语言的不同,可以使用不同的运算符或方法来实现。

算法

以下是连接两个字符串的算法。

1. 开始
2. 声明并初始化两个字符串。
3. 执行连接。
4. 打印结果。
5. 停止

示例

这里,我们看到了一个连接操作的实际实现,我们使用两个不同的字符串来组成一个新的字符串。 −

#include <stdio.h>
#include <string.h>
int main(){
   // 定义两个字符串
   char sOne[15] = "Tutorials";
   char sTwo[15] = "Point";
   // 连接字符串
   strcat(sOne, sTwo); 
   // 打印结果
   printf("New String: %s
", sOne); 
   return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main() {
   // 定义两个字符串
   string sOne = "Tutorials";
   string sTwo = "Point";
   // 连接字符串
   string newStr = sOne + sTwo; 
   // 打印结果
   cout <<"New String: "  << newStr << endl; 
}
public class ConctStr {
   public static void main(String []args){
      // 定义两个字符串
      String sOne = "Tutorials";
      String sTwo = "Point";
	  // 连接字符串
      String newStr = sOne + sTwo; 
	  // 打印结果
      System.out.println("New String: " + newStr); 
   }
}
# 定义两个字符串
sOne = "Tutorials"
sTwo = "Point"
# 连接字符串
newStr = sOne + sTwo 
# 打印结果
print("New String: " + newStr) 

输出

New String: TutorialsPoint

计算字符串长度

计算字符串长度意味着打印该字符串的字符数。例如,字符串"Tutorix"的长度为 7。字符串的长度可用于迭代其字符、访问给定索引处的特定字符或从原始字符串中切片子字符串。

算法

计算字符串长度的算法如下 −

1. 开始
2. 声明并初始化一个字符串。
3. 计算字符数。
4. 打印结果。
5. 停止

示例

以下是此操作在各种编程语言中的实现 −

#include <stdio.h>
#include <string.h>
int main() {
   // 给出的字符串为
   char name[] = "tutorialspoint";
   // 循环查找给定字符串的长度
   int strLength = 0;
   while (name[strLength] != '\0') {
      strLength++;
   }
   // 打印结果
   printf("给定字符串的长度为: %d
", strLength);
   return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main() {
   // 给出的字符串为
   string name = "tutorialspoint";
   // 查找给定字符串的长度
   int strLength = name.length();
   // 打印结果
   cout << "给定字符串的长度为: " << strLength << endl;
   return 0;
}
public class Main {
   public static void main(String[] args) {
      // 给出的字符串为
      String name = "tutorialspoint";
      // 查找给定字符串的长度
      int strLength = name.length();
      // 打印结果
      System.out.println("给定字符串的长度为: " + strLength);
   }
}

# 给出的字符串为
name = "tutorialspoint"
# 查找给定字符串的长度
length = len(name)
# 打印结果
print("给定字符串的长度为:", length) 

输出

给定字符串的长度为: 14

在字符串中查找子字符串

子字符串是指字符串的一部分或子集。在此操作中,我们需要找到给定子字符串的索引。

算法

假设我们有一个名为 newSubStr 的子字符串,我们需要找到它的索引号。以下是查找子字符串的算法。

1. 开始
2. 声明并初始化一个字符串。
3. 定义一个子字符串。
4. 检查子字符串的索引。
5. 如果找到,则打印子字符串第一个字符的索引,否则打印"-1"。
6. 停止

示例

在下面的示例中,我们将在各种编程语言中演示此操作 −

#include <stdio.h>
#include <string.h>
int main() {
    // 原始字符串
    char orgnlStr[] = "tutorialspoint";
    // 查找子字符串
    char newSubStr[] = "point";
    // 查找指向子字符串的指针
    char *indX = strstr(orgnlStr, newSubStr);
    // 检查子字符串是否存在
    if (indX == NULL) {
        printf("-1
");
    } else {
        printf("在索引处找到子字符串: %ld
", indX - orgnlStr);
    }
    return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main() {
    // 原始字符串
    string orgnlStr = "tutorialspoint";
    // 待查找的子字符串
    string newSubStr = "point";
    // 查找子字符串的索引
    int indX = orgnlStr.find(newSubStr);
    // 检查子字符串是否存在
   if (indX == -1) {
      cout << "-1" << endl;
   } else {
      cout << "在索引处找到子字符串: " << indX << endl;
   }
   return 0;
}
public class Substr {
   public static void main(String[] args) {
        // 原始字符串
        String orgnlStr = "tutorialspoint";
        // 待查找的子字符串
        String newSubStr = "point";
        // 查找子字符串的索引
        int indX = orgnlStr.indexOf(newSubStr);
        // 检查是否找到子字符串
        if (indX == -1) {
         System.out.println("-1");
        } else {
           System.out.println("在索引处找到子字符串: " + indX);
        }
   }
}
# 原始字符串
orgnlStr = "tutorialspoint"
# 查找子字符串
newSubStr = "point"
# 查找子字符串的索引
indX = orgnlStr.find(newSubStr)
# 检查是否找到子字符串
if indX == -1:
   print("-1")
else:
   print("在索引处找到子字符串:", indX) 

输出

在索引处找到子字符串: 9

反转字符串内容

在反转操作中,我们反转字符串中字符的顺序。这将生成一个新字符串,其中包含与原始字符串相同的字符,但顺序相反。

算法

假设我们有一个字符串,需要将其反转。以下是反转字符串的算法。

1. 开始
2. 声明一个空字符串。
3. 定义一个 for 循环来迭代原始字符串的字符。
4. 将每个字符附加到反转后的字符串。
5. 打印结果。
6. 停止

示例

以下是此操作在各种编程语言中的实现 −

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// function to reverse the string
char* rev_str(char* orgnlStr) {
    int len = strlen(orgnlStr);
    // 存储反转后的字符串
    char* revStr = (char*)malloc(len + 1);
    // 循环反转字符串
    for (int i = 0; i < len; i++) {
        revStr[i] = orgnlStr[len - i - 1];
    }
    // 返回反转后的字符串
    revStr[len] = '\0';
    return revStr;
}
int main() {
    printf("以相反的顺序打印字符串: 
");
    // 调用函数打印结果
    printf("%s
", rev_str("tutorials")); 
    printf("%s
", rev_str("point")); 
    return 0;
}
#include <iostream>
#include <string>
using namespace std;
// 反转字符串的函数
string rev_str(string orgnlStr) {
    // 初始化一个空字符串
    string revStr = "";
    // 循环反转字符串
    for (int i = orgnlStr.length() - 1; i >= 0; i--) {
        // 将每个字符附加到反转后的字符串
        revStr += orgnlStr[i];
    }
    // 返回反转后的字符串
    return revStr;
}
int main() {
   cout << "以相反的顺序打印字符串: " << endl; 
   // 调用函数打印结果
   cout << rev_str("tutorials") << endl; 
   cout << rev_str("point") << endl; 
   return 0;
}
public class Main {
    // 反转字符串的方法
    public static String rev_str(String orgnlStr) {
    // 初始化一个空字符串
    String revStr = "";
    // 循环反转字符串
    for (int i = orgnlStr.length() - 1; i >= 0; i--) {
        // 将每个字符附加到反转后的字符串
        revStr += orgnlStr.charAt(i);
    }
    // 返回反转后的字符串
    return revStr;
   }
   public static void main(String[] args) {
      System.out.println("以相反的顺序打印字符串:"); 
      // 调用方法打印结果
      System.out.println(rev_str("tutorials")); 
      System.out.println(rev_str("point")); 
   }
}
# 反转字符串的函数
def rev_str(orgnlStr):
    # 初始化一个空字符串
    revStr = ""
    # 循环反转字符串
    for i in range(len(orgnlStr) - 1, -1, -1):
        # 将每个字符附加到反转后的字符串
        revStr += orgnlStr[i]
    # 返回反转后的字符串
    return revStr
# 调用函数打印结果
print("以相反的顺序打印字符串:")
print(rev_str("tutorials")) 
print(rev_str("point")) 

输出

以相反的顺序打印字符串: 
slairotut
tniop

字符串索引

在此操作中,我们尝试借助索引来访问或定位特定字符。

算法

从给定字符串访问指定字符的算法如下 −

1. 开始
2. 声明并初始化一个字符串。
3. 查找指定字符的索引号。
4. 打印结果。
5. 停止

示例

这里,我们看到了索引操作的实际实现 −

#include <stdio.h>
#include <string.h>
int main(){
   char str[] = "Tutorials Point";
   char *ptr = strchr(str, 'o'); 
   int indX = ptr - str; 
   // 打印结果
   printf("The index of given character is: %d
", indX);
   return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main() {
   string str = "Tutorials Point";
   int indX = str.find('o');
   // 打印结果
   cout << "The index of given character is: " << indX << endl;
   return 0; 
}
public class Main {
   public static void main(String[] args) {
      String str = "Tutorials Point";
      int indX = str.indexOf('o'); 
      System.out.println("The index of given character is: " + indX);
   }  
}
# 定义字符串
str = "Tutorials Point"
indX = str.find('o')
# 打印结果
print("The index of given character is:", indX) 

输出

The index of given character is: 3