数据结构与算法之字符串反转

字符串反转是一个常见的算法问题,可以用多种方法实现。下面介绍几种实现字符串反转的常见算法。

  1. 使用数组

在Java等语言中,字符串是一个字符数组。我们可以通过访问和修改数组元素来反转字符串。

例如,可以首先将字符串转换为字符数组,然后使用从首尾两端遍历数组的循环,交换数组元素的位置实现字符串反转。具体代码如下:

public static String reverseString(String str) {
    
    
    char[] arr = str.toCharArray();
    int left = 0, right = arr.length - 1;
    while (left < right) {
    
    
        char temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
        left++;
        right--;
    }
    return new String(arr);
}
  1. 使用StringBuilder

StringBuilder是一个可变的字符序列,可以方便地进行字符串操作。我们可以使用StringBuilder的reverse()方法来实现字符串反转。

例如,可以首先将字符串转换为StringBuilder对象,然后使用reverse()方法将其反转。具体代码如下:

public static String reverseString(String str) {
    
    
    return new StringBuilder(str).reverse().toString();
}
  1. 使用递归

递归是一种将问题分解为更小的子问题的方法。我们可以使用递归来实现字符串反转。

例如,可以将字符串分成前半部分和后半部分,然后分别对它们进行递归反转,最后将它们连接起来得到反转后的字符串。具体代码如下:

public static String reverseString(String str) {
    
    
    if (str.length() <= 1)
        return str;
    return reverseString(str.substring(1)) + str.charAt(0);
}

这三种算法都可以实现字符串反转,具体选择哪种算法取决于具体的需求和场景。字符串反转是一个常见的算法问题,可以用多种方法实现。下面介绍几种实现字符串反转的常见算法。

  1. 使用数组

在Java等语言中,字符串是一个字符数组。我们可以通过访问和修改数组元素来反转字符串。

例如,可以首先将字符串转换为字符数组,然后使用从首尾两端遍历数组的循环,交换数组元素的位置实现字符串反转。具体代码如下:

public static String reverseString(String str) {
    
    
    char[] arr = str.toCharArray();
    int left = 0, right = arr.length - 1;
    while (left < right) {
    
    
        char temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
        left++;
        right--;
    }
    return new String(arr);
}
  1. 使用StringBuilder

StringBuilder是一个可变的字符序列,可以方便地进行字符串操作。我们可以使用StringBuilder的reverse()方法来实现字符串反转。

例如,可以首先将字符串转换为StringBuilder对象,然后使用reverse()方法将其反转。具体代码如下:

public static String reverseString(String str) {
    
    
    return new StringBuilder(str).reverse().toString();
}
  1. 使用递归

递归是一种将问题分解为更小的子问题的方法。我们可以使用递归来实现字符串反转。

例如,可以将字符串分成前半部分和后半部分,然后分别对它们进行递归反转,最后将它们连接起来得到反转后的字符串。具体代码如下:

public static String reverseString(String str) {
    
    
    if (str.length() <= 1)
        return str;
    return reverseString(str.substring(1)) + str.charAt(0);
}

这三种算法都可以实现字符串反转,具体选择哪种算法取决于具体的需求和场景。

在这里插入图片描述

一、C 实现 最长公共子串 及代码详解

最长公共子串是指在两个字符串中,找到最长的公共子串(substring),其特点是要求子串必须连续。下面给出 C 语言实现最长公共子串的代码及详解。

代码如下:

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

#define MAX_LEN 100 

void LongestCommonSubstring(char* str1, char* str2) {
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int temp[MAX_LEN][MAX_LEN];
    int max_len = 0, end_index = 0;
    memset(temp, 0, sizeof(temp));
    for (int i = 0; i < len1; i++) {
        for (int j = 0; j < len2; j++) {
            if (str1[i] == str2[j]) {
                if (i == 0 || j == 0) {
                    temp[i][j] = 1;
                }
                else {
                    temp[i][j] = temp[i - 1][j - 1] + 1;
                }
                if (temp[i][j] > max_len) {
                    max_len = temp[i][j];
                    end_index = i;
                }
            }
        }
    }
    printf("最长公共子串是:");
    for (int i = end_index - max_len + 1; i <= end_index; i++) {
        printf("%c", str1[i]);
    }
    printf("\n");
}

int main() {
    char str1[MAX_LEN], str2[MAX_LEN];
    printf("输入第一个字符串:");
    scanf("%s", str1);
    printf("输入第二个字符串:");
    scanf("%s", str2);
    LongestCommonSubstring(str1, str2);
    return 0;
}

首先请定义一个函数 LongestCommonSubstring,它有两个参数,分别表示两个字符串。接着我们需要计算出这两个字符串的长度,以便后面进行操作。定义一个二维数组 temp,大小为 MAX_LEN * MAX_LEN。temp[i][j] 表示 str1 字符串中以 i(包含 i)为结尾的子串与 str2 字符串中以 j(包含 j)为结尾的子串的最长公共子串的长度。把 temp 初始化为 0。

接着我们通过两个 for 循环,遍历两个字符串 str1 和 str2,如果 str1[i] == str2[j],表示找到了公共子串,接着分三种情况进行讨论:

  1. 如果 i = 0 或 j = 0,表示公共子串在 str1 或 str2 的开头,此时 temp[i][j] 的值为 1。

  2. 如果 i > 0 且 j > 0,表示公共子串在中间位置,此时 temp[i][j] 的值为 temp[i - 1][j - 1] + 1。

  3. 如果 temp[i][j] > max_len,表示找到了新的最长公共子串,此时更新 max_len 的值和 end_index 的值。

接着我们输出最长公共子串,从 str1[end_index - max_len + 1] 到 str1[end_index] 就是最长公共子串。

最后在主函数中输入两个字符串,调用 LongestCommonSubstring 函数即可。最长公共子串是指在两个字符串中,找到最长的公共子串(substring),其特点是要求子串必须连续。下面给出 C 语言实现最长公共子串的代码及详解。

代码如下:

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

#define MAX_LEN 100 

void LongestCommonSubstring(char* str1, char* str2) {
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int temp[MAX_LEN][MAX_LEN];
    int max_len = 0, end_index = 0;
    memset(temp, 0, sizeof(temp));
    for (int i = 0; i < len1; i++) {
        for (int j = 0; j < len2; j++) {
            if (str1[i] == str2[j]) {
                if (i == 0 || j == 0) {
                    temp[i][j] = 1;
                }
                else {
                    temp[i][j] = temp[i - 1][j - 1] + 1;
                }
                if (temp[i][j] > max_len) {
                    max_len = temp[i][j];
                    end_index = i;
                }
            }
        }
    }
    printf("最长公共子串是:");
    for (int i = end_index - max_len + 1; i <= end_index; i++) {
        printf("%c", str1[i]);
    }
    printf("\n");
}

int main() {
    char str1[MAX_LEN], str2[MAX_LEN];
    printf("输入第一个字符串:");
    scanf("%s", str1);
    printf("输入第二个字符串:");
    scanf("%s", str2);
    LongestCommonSubstring(str1, str2);
    return 0;
}

首先请定义一个函数 LongestCommonSubstring,它有两个参数,分别表示两个字符串。接着我们需要计算出这两个字符串的长度,以便后面进行操作。定义一个二维数组 temp,大小为 MAX_LEN * MAX_LEN。temp[i][j] 表示 str1 字符串中以 i(包含 i)为结尾的子串与 str2 字符串中以 j(包含 j)为结尾的子串的最长公共子串的长度。把 temp 初始化为 0。

接着我们通过两个 for 循环,遍历两个字符串 str1 和 str2,如果 str1[i] == str2[j],表示找到了公共子串,接着分三种情况进行讨论:

  1. 如果 i = 0 或 j = 0,表示公共子串在 str1 或 str2 的开头,此时 temp[i][j] 的值为 1。

  2. 如果 i > 0 且 j > 0,表示公共子串在中间位置,此时 temp[i][j] 的值为 temp[i - 1][j - 1] + 1。

  3. 如果 temp[i][j] > max_len,表示找到了新的最长公共子串,此时更新 max_len 的值和 end_index 的值。

接着我们输出最长公共子串,从 str1[end_index - max_len + 1] 到 str1[end_index] 就是最长公共子串。

最后在主函数中输入两个字符串,调用 LongestCommonSubstring 函数即可。

在这里插入图片描述

二、C++ 实现 最长公共子串 及代码详解

最长公共子串是指两个或多个字符串中最长的公共子串。下面给出C++实现最长公共子串的算法,其中采用动态规划的思想,时间复杂度为O(mn)。

代码如下:

#include <iostream>
#include <cstring>

using namespace std;

int LCS(string str1, string str2)
{
    int m = str1.size();
    int n = str2.size();
    int longest = 0;
    int matrix[m+1][n+1];
    memset(matrix, 0, sizeof(matrix)); // 初始化为0

    for (int i = 1; i <= m; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (str1[i-1] == str2[j-1])
            {
                matrix[i][j] = matrix[i-1][j-1] + 1;
                if (matrix[i][j] > longest)
                {
                    longest = matrix[i][j];
                }
            }
            else
            {
                matrix[i][j] = 0;
            }
        }
    }
    return longest;
}

int main()
{
    string str1 = "abcdxyz";
    string str2 = "xyzabcd";
    int result = LCS(str1, str2);
    cout << "Length of longest common substring is: " << result << endl;
    return 0;
}

上述代码定义了一个函数LCS,它接收两个参数,即两个字符串,返回它们的最长公共子串的长度。主程序中调用LCS函数,并输出结果。

采用动态规划的思路,通过一个二维数组来保存最长公共子串的长度,数组中的第i行和第j列表示str1的前i个字符和str2的前j个字符的最长公共子串的长度。如果str1[i-1]等于str2[j-1],则matrix[i][j]等于matrix[i-1][j-1]+1,否则matrix[i][j]等于0。

最后,遍历整个matrix数组,找到其中的最大值,即为最长公共子串的长度。最长公共子串是指两个或多个字符串中最长的公共子串。下面给出C++实现最长公共子串的算法,其中采用动态规划的思想,时间复杂度为O(mn)。

代码如下:

#include <iostream>
#include <cstring>

using namespace std;

int LCS(string str1, string str2)
{
    int m = str1.size();
    int n = str2.size();
    int longest = 0;
    int matrix[m+1][n+1];
    memset(matrix, 0, sizeof(matrix)); // 初始化为0

    for (int i = 1; i <= m; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (str1[i-1] == str2[j-1])
            {
                matrix[i][j] = matrix[i-1][j-1] + 1;
                if (matrix[i][j] > longest)
                {
                    longest = matrix[i][j];
                }
            }
            else
            {
                matrix[i][j] = 0;
            }
        }
    }
    return longest;
}

int main()
{
    string str1 = "abcdxyz";
    string str2 = "xyzabcd";
    int result = LCS(str1, str2);
    cout << "Length of longest common substring is: " << result << endl;
    return 0;
}

上述代码定义了一个函数LCS,它接收两个参数,即两个字符串,返回它们的最长公共子串的长度。主程序中调用LCS函数,并输出结果。

采用动态规划的思路,通过一个二维数组来保存最长公共子串的长度,数组中的第i行和第j列表示str1的前i个字符和str2的前j个字符的最长公共子串的长度。如果str1[i-1]等于str2[j-1],则matrix[i][j]等于matrix[i-1][j-1]+1,否则matrix[i][j]等于0。

最后,遍历整个matrix数组,找到其中的最大值,即为最长公共子串的长度。

在这里插入图片描述

三、Java 实现 最长公共子串 及代码详解

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_47225948/article/details/133124396