C++ 将给定的字符串最小分割以获得另一个字符串

C++ 将给定的字符串最小分割以获得另一个字符串

在这个问题中,我们需要通过切割另一个字符串来构造一个字符串。我们可以使用最长公共子串来解决这个问题。我们可以找到两个字符串之间的最长公共子串,将str1切割成1或2部分,并从str2中移除该子串。然后,我们在更新后的字符串中再次找到最长公共子串,并按照它的方式进行,直到str2变为空。通过这种方式,我们可以解决这个问题。

问题陈述 - 我们给定了不同长度的str1和str2字符串。我们需要通过切割和连接str1的部分来构造字符串str2。我们需要找到需要切割str1的最小次数,才能得到str2字符串。如果无法构造str2字符串,则打印’1’。

示例示例

输入

str1 = "tutorialspoint"; str2 = "intpotu";

输出

3

解释: 如下所示,我们需要将str1切成4块,进行3次切割。

Tu | torials | po | int

输入:

str1 = "tutorialspoint"; str2 = "intpotu";

输出

-1

解释 - 由于无法从str1构造str2,因此打印“-1”。

输入

str1 = "Welcome"; str2 = "meWe";

输出

2

说明 - 我们|欢迎

方法1

在这个方法中,我们将找到给定字符串之间的最长公共子串,切割字符串并从两个字符串中删除子串。此外,我们会在每次迭代中更新两个字符串,直到str2字符串变为空。

此外,我们还需要注意切割起始部分和结束部分,因为在这种情况下我们只需要1个切片。此外,如果字符已经在子串中计数过了,我们将字符str1更新为“0”。

算法

步骤1 - 如果str1的大小小于str2,则返回-1,因为无法构建str2。如果两个字符串相同,则返回0。

步骤2 - 初始化’answer’为0,用于存储str1的总切片数。

步骤3 - 使用while循环进行迭代,直到str2的大小大于零。

步骤4 - 执行longCommonSubStr()函数以获取str1和str2中的最长公共子串。

步骤4.1 - 在longCommonSubStr()函数中,用0初始化’maxLen’变量以存储最大长度,用0初始化’endingStr1’和’endingStr2’以存储子串在str1和str2中的结束索引。此外,使用动态规划方法来找到最长公共子串并将其存储在’mat’中的前一个结果,并将’currentRow’初始化为0。

步骤4.2 - 开始填充二维矩阵。

步骤4.3 - 如果p和q都为0,则将零存储在mat[currentRow][q]中。

步骤4.4 - 如果str1中索引为(p-1)的字符和str2中索引为(q-1)的字符相同,则通过将其添加到先前的对角线项来更新mat[currentRow][q]的值。

步骤4.5 - 如果更新后的值大于maxLen变量的值,则更新’maxLen’,’endingStr1’和’endingStr2’的值。

步骤4.6 - 否则,将0赋值给mat[currentRow][q] = 0,因为我们需要开始一个新的子串。

步骤4.7 - 迭代嵌套循环完成后,更新’currentRow’变量的值。

步骤4.8 - 创建’temp’数组以存储最长公共子串的长度、str1和str2的结束索引。最后,返回’temp’数组。

步骤5 - 在getMinSlices()函数中,如果最长公共子串的长度为0,则返回-1。

第6步 - 如果子字符串的起始索引为0,在str1中,如果最接近子字符串的下一个字符不是’0’,则将’answer’值增加1。如果结束索引等于’len – 1’,在子字符串前的字符不是’0’,则将’answer’值增加1。如果是’0’,则该部分已经被切割,因此不需要增加’answer’值。

第7步 - 如果我们需要从中间切割字符串,在str1中,如果子字符串的前一个字符和后一个字符都不等于’0’,则相应地增加’answer’值。

第8步 - 使用substr()方法从str2中删除公共子字符串。

第9步 - 通过执行replaceSubStr()函数,将所有子字符串字符替换为’0’,来更新str1字符串。

第9.1步 - 在replaceSubStr()函数中,使用substr()方法从字符串中获取初始子字符串。然后,创建一个包含与子字符串长度相等的零字符的中间字符串,并获取结束子字符串。

第9.2步 - 在连接初始、中间和结束字符串后,返回字符串。

第10步 - 返回’answer’值。

示例

#include <bits/stdc++.h>
using namespace std;
int *longCommonSubStr(string str1, string str2) {
    // String sizes
    int len1 = str1.size();
    int len2 = str2.size();
    // To store the maximum length of the common substring.
    int maxLen = 0;
    // For storing the ending index of the substring.
    int endingStr1 = 0;
    int endingStr2 = 0;
    // 2D array to store max len of consecutive rows
    int mat[2][len1 + 1];
    // Pointer to the row
    int currentRow = 0;
    // Finding the longest common substring
    for (int p = 0; p <= len1; p++) {
        for (int q = 0; q <= len2; q++) {
            if (p == 0 || q == 0) {
                mat[currentRow][q] = 0;
            } else if (str1[p - 1] == str2[q - 1]) {
                mat[currentRow][q] = mat[1 - currentRow][q - 1] + 1;
                // If we get longer substring, update values.
                if (mat[currentRow][q] > maxLen) {
                    maxLen = mat[currentRow][q];
                    endingStr1 = p - 1;
                    endingStr2 = q - 1;
                }
            } else {
                mat[currentRow][q] = 0;
            }
        }
        // Change the current row
        currentRow = 1 - currentRow;
    }
    // Storing the starting index of longest common substring
    int *temp = new int[3];
    temp[0] = (endingStr1 - maxLen + 1);
    temp[1] = (endingStr2 - maxLen + 1);
    temp[2] = maxLen;
    return temp;
}
string replaceSubStr(string str1, int ind, int sub_len) {
    // Get initial string
    string start = str1.substr(0, ind);
    string mid = "";
    // Create string with all 0's
    for (int p = 0; p < sub_len; p++) {
        mid += "0";
    }
    // Get remaining string
    string end = str1.substr(ind + sub_len);
    // Return final string
    return (start + mid + end);
}
int getMinSlices(string str1, string str2) {
    // Return -1 if length of str2 is greater
    if (str1.size() < str2.size())
        return -1;
    // Handle the case when both strings are equal.
    if (str1 == str2)
        return 0;
    int answer = 0, len1 = (str1.size() - 1);
    // Find longest common substring of str1 and str2, until str2 is empty.
    while (str2.size() > 0) {
       int *lcs = longCommonSubStr(str1, str2);
        // If the length of the substring is 0, return -1
        if (lcs[2] == 0)
            return -1;

        // Handling the case when starting point is 0, or the ending point is len1
        if ((lcs[0] + lcs[2] - 1 == len1) || lcs[0] == 0) {
            // If the startind index is 0, and the last character is not '0', we need to slice. Otherwise, it's already sliced.
            if (lcs[0] == 0) {
                if (str1[lcs[0] + lcs[2]] != '0')
                    answer++;
            } else {
                // If the ending index is len1, the previous character of the substring's first character is '0', last part of the string is already sliced.
                if (str1[lcs[0] - 1] != '0')
                    answer++;
            }
        }
        // When the substring is between the last and ending character
        else {
            // Increment answer value if strings are not sliced already.
            if (str1[lcs[0] + lcs[2]] != '0') {
                answer++;
            } 
            if (str1[lcs[0] - 1] != '0') {
                answer++;
            }
        }
        // Remove lcs from str2.
        str2 = str2.substr(0, lcs[1]) + str2.substr(lcs[1] + lcs[2]);
        // Pleace '0' in str1 at the place of lcs
        str1 = replaceSubStr(str1, lcs[0], lcs[2]);
    }
    // final output
    return answer;
}
int main() {
    string str1 = "tutorialspoint";
    string str2 = "intpotu";
    cout << "The minimum slices of string str1 is required to construct a string str2 is " << getMinSlices(str1, str2) << endl;
}

输出

The minimum slices of string str1 is required to construct a string str2 is 3

时间复杂度 – O(NMM),其中 O(N*M) 用于找到最长公共子串,O(M) 用于缩小字符串 str2。

空间复杂度 – O(N),其中 O(N) 用于存储动态规划结果。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程