String -- algorithm summary

1. Copy of string

char *scopy(char *str1,const char *str2);  
intmain()  
{  
    char s1[50];  
    scopy(s1,"I am happy!");  
    printf("%s\n",s1);  
    return 0;  
}  
  
char *scopy(char *str1,const char *str2)  
{  
    int i=0,j=0;  
    while(str2[i]!='\0')  
    {  
        str1[j]=str2[i];  
        i++;  
        j++;  
    }  
    str1[j]='\0';  
    return str1;  
}  

2. The palindrome of the string

Check if a string is a palindrome

#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;     
    while(cin>>str){
        bool flag=true;
        int i,j;        
        for(j=str.size()-1,i=0;j>=0;j--,i++){
            if(str[j]!=str[i]){
                flag=false;
                break;
            }                      
        }
        if(flag) cout<<"Yes!"<<endl;
        else cout<<"No!"<<endl;    
    }
    return 0;
}

Find the longest palindrome substring in a string (horse carriage)

      To calculate the longest palindrome substring in a string, we use the following five methods:
1) Brute-force solution, no need to discuss odd strings and even strings separately, only the work of determining elements forward and backward is required at the same time, through Continue to shrink the string from the left to find its palindrome substring, and then get the longest palindrome substring;
2) Center expansion method: traverse each character, and then expand to the left and right sides with the character as the center, from left to right If you move, you can get the longest palindrome substring, but you need to pay attention to the difference between odd and even palindrome substrings, and need to be processed differently;
3) Optimization of center expansion: Distinguishing technology from even numbers makes the program very redundant. Why not transform the original string so that the program only deals with odd or even types? Here we choose to transform the original string into an odd string for processing;
4) Dynamic programming: Because we know that the substring of the longest palindrome string must be a palindrome, we can use the dynamic programming rule to solve, using map[i][j] judges whether the array from i to j is a palindrome. If s[i-1]==s[j+1], it can be judged in O(1) time [i-1, j+1] is a palindrome;

5) The manacher algorithm, for the solution of the longest palindrome, we can use the Manacher algorithm to control the time complexity of the algorithm in linear time.

#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <deque>
using namespace std;
/*
For solving the longest palindrome substring, we have tried 5 methods to solve:
1) The brute force algorithm has a very high time complexity;
2) Classification brute force algorithm, which analyzes odd and even numbers separately;
3) The classification brute force algorithm is optimized to avoid parity analysis by constructing new strings;
4) The dynamic programming algorithm is used to solve the problem. The subclass of the palindrome Zichuan must be a palindrome substring, and the dynamic programming algorithm is used to solve it;
5) Use the most constant Manacher algorithm to solve
*/ // brute force algorithm
int longest_ror_String(string s,vector<char>& v){
    int len = s.length();
    int count, max = 0;
    bool flag = false;
    vector<char> vec_temp;
    for (int i = 0; i < len; i++){
        int ki = i;
        count = 0;
        for (int j = len - 1; j > i; j--){
            int kj = j;
            vector<char> vec;
            while (s[ki] == s[kj]){
                count++;
                vec.push_back(s[ki]);
                if (ki == kj || ki + 1 == kj)
                {   
                    if (ki == kj){
                        count = (count - 1) * 2 + 1;
                    }
                    else{
                        count = count * 2;
                    }
                    flag = true;
                    vec_temp = vec;
                    break;
                }
                ki++;
                kj--;
            }
            if (flag == true) break;
        }
        if (max < count) {
            v = vec_temp;
            max = count;
        }
    }
    cout << max << endl;
    return max;
} //Classification brute force algorithm
string longestPalindrome(string s){
    int max1 = 0;//Odd longest substring
    int max2 = 0;//even longest substring
    int idx1 = 0;//The center character of the odd longest substring
    int idx2 = 0;//The center character of the even longest substring
    string result;
    // Calculate the odd longest palindrome string
    for (int i = 0; i < s.length(); i++){

        //Note that we have different strategies for odd and even palindrome substrings,
        //Odd number, ++z and --j operations can be performed directly in while
        //Even numbers, ++z and --j operations cannot be performed directly in while, because it is necessary to compare whether s[z] and s[j] are the same?

        //Calculate the odd longest palindrome string. Note that j, z, count1, count2 are defined inside the for loop. If they are placed outside, it is easy to be modified and unexpected problems will occur, so you need to pay attention to the definition method
        int j = i;
        int z = i;
        int count1 = 0;
        int count2 = 0;
        while ((++z < s.length() && (--j >= 0) && s[z] == s[j])){
            count1 += 2;
            if (count1>max1){
                max1 = count1;
                idx1 = i;
            }
        }

        //Calculate the longest even-numbered palindrome string
        j = i;
        z = i + 1;
        while ((z < s.length()) && (j >= 0) && (s[z] == s[j])){
            count2 += 2;
            if (count2>max2){
                max2 = count2;
                idx2 = i;
            }
            with ++;
            j--;
        }
    }
    if (max1 + 1 > max2) result = s.substr(idx1 - max1 / 2, max1 + 1);
    else result = s.substr(idx2 - max2 / 2 + 1, max2);
    return result;
} //Classification brute force algorithm optimization
//By transforming the string, the program does not need to distinguish between parity and even
//aba is transformed into #a#b#a#, and abba is transformed into #a#b#b#a#, that is, all odd numbers are processed!
string longestPalindrome_better(string s){
    int max = 0;
    int idx = 0;
    string temp[2005];
    int j = 0;
    for (int i = 0; i < s.size(); i++){
        temp[j++] = '#';
        temp[j++] = s[i];
    }
    temp[j++] = '#';
    temp[j] = '\0';
    for (int i = 0; i < 2 * s.size() + 1; i++){
        int j = i;
        int z = i;
        int count = 0;

        while ((++z) < (2 * s.size() + 1) && (--j >= 0) && (temp[z] == temp[j])){
            count++;
            if (count > max){
                max = count;
                idx = i;
            }
        }
    }
    return s.substr((idx - max) / 2, max);
}
// dynamic programming
string longestPalindrome_DP(string s){
    int len = s.length();
    int idx = 0;
    int max = 1;
    int map[1000][1000] = { 0 };
    //Initialize odd-numbered palindrome substrings
    for (int i = 0; i < len; i++){
        map[i][i] = 1;
    }
    //Initialize even palindrome substring
    for (int i = 0; i < len - 1; i++){
        if (s[i] == s[i + 1]){
            map[i][i + 1] = 1;
            idx = i;
            max = 2;
        }
    }
    for (int plen = 3; plen <= len; plen ++) {
        for (int j = 0; j < len - plen + 1; j++){
            int z = plen + j - 1;
            if (s[j] == s[z] && map[j + 1][z - 1]){
                map[j][z] = 1;
                idx = j;
                max = plen;
            }
        }
    }
    return s.substr(idx, max);
} //horse carriage
string longestPalindrome_Manacher(string s){
    string temp;
    temp += "$#";
    for (int i = 0; i < s.size(); i++){
        temp += s[i];
        temp += "#";
    }
    int *p = new int[temp.length()];
    memset(p, 0, sizeof(p));
    //max records the length of the longest palindrome substring, and idx records the center position of the longest palindrome string
    int max = 0, idx = 0;
    //mx记录i之前的最长回文子串延伸到最右边的位置,id记录该字符串的中心位置
    int mx = 0, id = 0;
    //因为第一个是'$'字符,所以不用计算它的p值
    for (int i = 1; i < temp.length(); i++){
        if (mx > i){
            p[i] = (p[2 * id - i] < (mx - i) ? p[2 * id - i] : (mx - i));
        }
        else{
            p[i] = 1;
        }
        while (i + p[i] < temp.length() && temp[i - p[i]] == temp[i + p[i]]){
            p[i]++;
        }
        if (i + p[i] > mx){
            id = i;
            mx = i + p[i];
            if (p[i] > max){
                max = p[i];
                idx = id;
            }
        }
    }
    max--;
    delete p;
    return s.substr((idx - max) / 2, max);

}
int main(){
    string s = "asdfjafhellololleh";
    string s1 = "level";
    vector<char> vec;
    string s2 = longestPalindrome(s);
    cout << s2 << endl;
    string s3=longestPalindrome_DP(s);
    cout << s3 << endl;
    string s4 = longestPalindrome_Manacher(s);
    cout << s4 << endl;
    return 0;
}

Given a string s, you can remove some characters from it so that the remaining string is a palindrome. How to delete to make the palindrome longest? That is, the minimum number of characters to be deleted is output, and the number of characters to be deleted is output.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int helper(string s)
{
    string rev = s;
    reverse(rev.begin(), rev.end());
    int size = s.size();
    vector<vector<int>> c(size + 1, vector<int>(size + 1));
    for (int i = 1; i <= size; ++i)
        for (int j = 1; j <= size; ++j)
        {
            if (s[i - 1] == rev[j - 1])
            {
                c[i][j] = c[i - 1][j - 1] + 1;
            }
            else if (c[i-1][j] >= c[i][j-1])
            {
                c[i][j] = c[i - 1][j];
            }
            else if (c[i - 1][j] < c[i][j - 1])
            {
                c[i][j] = c[i][j - 1];
            }
        }
    //Print
    /*
    for (int i = size, j = size; i >= 1 && j >= 1;)
    {
        if (s[i - 1] == rev[j - 1])
        {
            cout << s[i - 1] << " ";
            --i;
            --j;
        }
        else if (c[i][j - 1] >= c[i - 1][j])
        {
            --j;
        }
        else if (c[i][j - 1] < c[i - 1][j])
        {
            --i;
        }
    }
    */
    return size - c[size][size];
}
intmain()
{
    string s;
    while (cin >> s)
        cout << helper(s) << endl;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324645943&siteId=291194637