zoukankan      html  css  js  c++  java
  • 字符串算法总结

    • 数字转字符串
    • 字符串逆置(char*、string、折半法逆置字符串、异或法逆置字符串)
    • 字符串逆置保持单词不变
    • 实现strcpy,strcat,strcmp,strstr
    • 最长公共子串(这个博客里讲的比较好,这里我只是自己实现了一下,子串我的博客里已经讲过了 http://blog.sina.com.cn/s/blog_54f82cc20100zi4b.html
    • 最长公共子序列(和子串很像,只是状态转移公式不太一样:字符相等arr[i][j]=arr[i-1][j-1]+1;/字符不等arr[i][j]=max(arr[i][j-1],arr[i-1][j]);然后返回arr[len1][len2]就是最长公共子序列的长度;)
    • 回文串(和逆置后的字符串是否相等,leetcode有道很难的最短回文串的题目,是加最少的字符使其成为回文串214. Shortest Palindrome博客里有总结,是利用了KMP里的next数组)
    • 字符串最后一个单词的长度(华为OJ上的题热门第一- -|||,cin以空格为结束,所以用getline读取字符串,然后从最后找到空格,length减去找到空格的下标减一即可,当然我是用循环做的,为什么都是90分!!怒)
    • 大数加法(字符串加法)
    • 大数乘法(字符串减法)
    #include<iostream>
    #include<string>
    #include<assert.h>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    
    //数字转字符串
    string InttoChar(int num) {
        if (num == 0)
            return "0";
        string res;
        while (num != 0) {
            int tmp = num % 10;
            char ctmp = tmp + '0';
            res.push_back(ctmp);
            num /= 10;
        }
        reverse(res.begin(), res.end());
        return res;
    }
    //字符串逆置
    string reversestring(string s1) {
        if (s1 == "")
            return s1;
        string s2 = "";
        for (int i = s1.length() - 1; i >= 0; i--) {
            s2 += s1[i];
        }
        return s2;
    }
    //折半法逆置字符串
    char* revetsestring(char* s1) {
        if (s1 == NULL)
            return s1;
        int len = strlen(s1);
        char* p1, *p2;
        p1 = s1, p2 = s1 + len - 1;
        char tmp;
        while (p1 != p2) {
            tmp = *p1;
            *p1 = *p2;
            *p2 = tmp;
    
            p1++;
            p2--;
        }
        return s1;
    }
    //异或法逆置字符串
    char* revetsestr(char* str) {
        if (str == NULL)
            return str;
        char* f = str, *b = str + strlen(str) - 1;
        while (f<b) {
            *f ^= *b;
            *b ^= *f;
            *f ^= *b;
            f++;
            b--;
        }
        return str;
    }
    //字符串逆置单词内部顺序不变
    char* ReverseWords(char* s1) {
        int len = strlen(s1);
        if (s1 == NULL || len == 1)
            return s1;
        int i = len - 1, j = len;  //ij记录单词的位置
        int t = 0; //暂存已经录入单词的位置
        char* res = new char[len + 1]; //len不包含''要申请len+1个
        int k = 0;  //新字符串的位置
        while (i>0) {
            while (s1[i] != ' '&&i != 0)
                i--;
            t = i;
            if (i != 0)
            {
                i++;
                while (i<j) {
                    res[k++] = s1[i++];
                }
                res[k++] = ' ';
                j = t;
                i = t - 1;
            }
            else {
                while (i<j)
                {
                    res[k++] = s1[i++];
                }
                i = t;
            }
    
        }
        res[len] = '';
        return res;
    }
    
    //分别实现strcpy,strcat,strcmp,strstr
    //strcpy需要一个指针记录开始的位置
    char* stringcpy(char* des, char* src) {
        if (src == NULL)
            return src;
        int len = strlen(src);
        des = new char[len + 1];
        char* res = des;
        while (*src != '')
            *des++ = *src++;
        *des = '';
        return res;
    }
    
    
    //strcat,strcat需要des保证可以容纳src,我们这里不需要
    char* stringcat(char* des, char*src) {
        if (src == NULL)
            return des;
        int len1 = strlen(des);
        int len2 = strlen(src);
        char* newstr = new char[len1 + len2 + 1];
        char* res = newstr;
        while (*des != '')
            *newstr++ = *des++;
        while (*src != '')
            *newstr++ = *src++;
        *newstr = '';
        return res;
    }
    
    
    //strcmp,使用assert要包含其头文件assert.h不满足assert条件会报错
    int stringcmp(char* s1, char* s2) {
    
        assert((s1 != NULL) && (s2 != NULL));
        while (*s1&&*s2 && (*s1 == *s2)) {
            s1++;
            s2++;
        }
        return *s1 - *s2;
    }
    
    //strstr leetcode有原题,做过
    bool samestr(char* s1, char* s2) {
        if (strlen(s1) != strlen(s2))
            return false;
        while (*s1) {
            if (*s1 == *s2) {
                s1++;
                s2++;
            }
            else return false;
        }
        return true;
    }
    char* stringstr(char* s1, char* s2) {
        if (s1 == NULL || s1 == NULL)
            return NULL;
        int len1 = strlen(s1);
        int len2 = strlen(s2);
        if (len2>len1)
            return NULL;
        if (len1 == len2) {
            if (samestr(s1, s2))
                return s1;
            else return NULL;
        }
    
        for (int i = 0; i<len1;) {
            char* tmp = NULL;
            for (int j = 0; j<len2; j++)
                tmp += s1[i + j];
            tmp += '';
            if (samestr(tmp, s2))
                return s1 + i;
            else i++;
        }
        return NULL;
    }
    //最长公共子串
    string MaxSubstring(string& s1, string& s2) {
        if (s1 == "" || s2 == "")
            return "";
        int len1 = s1.length();
        int len2 = s2.length();
    
        int arraystr[100][100] = { 0 };//then the max length of string is 1000
        for (int i = 0; i<len1; i++) {
            for (int j = 0; j<len2; j++) {
                if (s1[i] == s2[j])
                {
                    if (i == 0 || j == 0)
                        arraystr[i][j] == 1;
                    else arraystr[i][j] = arraystr[i - 1][j - 1] + 1;
                }
                else arraystr[i][j] = 0;
            }
        }
    
        int maxlen = 0;
        int maxindex = 0;
        for (int i = len1 - 1; i >= 0; i--) {
            for (int j = len2 - 1; j >= 0; j--) {
                if (arraystr[i][j]>maxlen) {
                    maxlen = arraystr[i][j];
                    maxindex = j;
                }
            }
        }
        string res = "";
        for (int k = maxindex - maxlen + 1; k <= maxindex; k++)
            res += s2[k];
        return res;
    }
    //最长公共子序列长度
    int Maxsubsequencelength(string& s1, string& s2) {
        if (s1 == "" || s2 == "")
            return 0;
        int arraystr[1010][1010] = { { 0,0 } };
        int len1 = s1.length();
        int len2 = s2.length();
    
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (s1[i - 1] == s2[j - 1])
                    arraystr[i][j] = arraystr[i - 1][j - 1] + 1;
                else arraystr[i][j] = max(arraystr[i - 1][j], arraystr[i][j - 1]);
            }
        }
        return arraystr[len1][len2];
    }
    
    
    string Maxsubsequence(string& s1, string& s2) {   //输入时字符串长的那个为第一参数
        string res = "";
        if (s1 == "" || s2 == "")
            return res;
        int arraystr[100][100] = { { 0,0 } };
        int len1 = s1.length();
        int len2 = s2.length();
    
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (s1[i - 1] == s2[j - 1])
                    arraystr[i][j] = arraystr[i - 1][j - 1] + 1;
                else arraystr[i][j] = max(arraystr[i - 1][j], arraystr[i][j - 1]);
            }
        }
    
        for (int i = len1; i >= 0;) {
            for (int j = len2; j >= 0;) {
                if (arraystr[i][j]>max(max(arraystr[i - 1][j], arraystr[i][j - 1]), arraystr[i - 1][j - 1])) {
                    res = s1[i] + res;
                    i--;
                    j--;
                }
                else {
                    if (arraystr[i][j] == arraystr[i - 1][j - 1]) {
                        i--;
                        j--;
                    }
                    else if (arraystr[i][j] == arraystr[i - 1][j])
                        i--;
                    else if (arraystr[i][j] == arraystr[i][j - 1])
                        j--;
                }
            }
        }
        return res;
    }
    
    //最后一个单词的长度
    int lastword(string s1) {
        if (s1 == "")
            return 0;
        int len = s1.length();
        int i = len - 1;
        int res = 0;
        while (i >= 0 && s1[i] == ' ') {
            i--;
        }
        while (i >= 0 && s1[i] != ' ') {
            i--;
            res++;
        }
        return res;
    }
    int lastwordlen(string s1) {
        getline(cin, s1);
        if (s1 == "")
            cout << 0 << endl;
        return s1.length() - s1.rfind(' ') - 1;
    
    }
    //回文串
    bool isPalindrome(string s1) {
        string s2 = s1;
        reverse(s2.begin(), s2.end());
        if (s1 == s2)
            return true;
        else return false;
    
    }
    //字符串大数加法
    string stringadd(string& s1, string& s2) {
        int len1 = s1.length();
        int len2 = s2.length();
        if (len1 == 0)
            return s2;
        if (len2 == 0)
            return s1;
    
        int mlen = max(len1, len2);
    
        int* arr1 = new int[mlen];//把字符串数字转换成数组存储,在进行加和然后转成字符串
        int* arr2 = new int[mlen];
        int index = mlen - 1;
        for (int i = len1 - 1, j = len2 - 1; i >= 0 || j >= 0; index--) {
            if (i >= 0)
                arr1[index] = s1[i--] - '0';
            else arr1[index] = 0;
            if (j >= 0)
                arr2[index] = s2[j--] - '0';
            else arr2[index] = 0;
        }
    
        int* res = new int[mlen + 1];
        int carr = 0;
        int k = mlen - 1, l = mlen;
        while (k >= 0) {
            int tmp = arr1[k] + arr2[k] + carr;
            carr = tmp / 10;
            res[l--] = tmp % 10;
            k--;
        }
        if (carr != 0)
            res[0] = carr;
        else res[0] = 0;
        string ret = "";
        for (int i = 0; i <= mlen; i++) {
            if (res[i] == 0)
                continue;
            char c = '0' + res[i];
            ret = ret + c;
    
        }
        return ret;
    }
    //字符串大数乘法
    char* MultiString(char* str1, char* str2) {
    
        int len1 = strlen(str1), len2 = strlen(str2);
        if (len2>len1) {              //len1,str1对应较长的字符串
            char* temp = str1;
            int temp1 = len1;
            str1 = str2;
            str2 = temp;
            len1 = len2;
            len2 = temp1;
        }
    
        char* ret = new char[len1 + len2];
        memset(ret, '0', sizeof(char)*(len1 + len2 - 1));  //初始化字符串
        ret[len1 + len2 - 1] = '';
    
        if (len1 == 0 || len2 == 0)
            return ret;
        int temp1 = 0, temp2 = 0;
        for (int i = len2 - 1; i >= 0; i--) {
            int carry = 0;
            for (int j = len1 - 1; j >= 0; j--) {
                int sum = ret[i + j] - '0';
                if (carry>0)
                    sum += carry;
                temp1 = str1[j] - '0';
                temp2 = str2[i] - '0';
                sum += temp1*temp2;
                if (sum >= 10) {
                    carry = sum / 10;
                }
                else carry = 0;
                ret[i + j] = sum % 10 + '0';  //规格化处理
                if (j == 0 && carry>0)    //最高位以后还有可能进位
                    ret[i - 1] += carry;
            }
            cout << i << "    " << ret << endl;
        }
    
        char* p = ret;
        while (*p == '0')   //如果前面有0,从第一位不是0开始输出
            p++;
        cout << p << endl;
        return p;
    }
    
    
    
    
    int main() {
        int num = 1234569;
        string res = InttoChar(num);
        cout << res << endl;
    
        char* test = "guofei is a student in SEU!";
        string test1 = "helloworld";
        char* test2 = "happyforever";
        cout << reversestring(test2) << endl;
        cout << reversestring(test1) << endl;
        cout << ReverseWords(test) << endl;
    
        char* s1, *s2 = "cpy this string";
        cout << stringcpy(s2, s2) << endl;
        cout << stringcmp(test, test2) << endl;
    
        char* s3 = "auti";
        char* s4 = "beautiful girl";
        if (stringstr(s3, s4))
            cout << "fei zi chuan" << endl;
        else cout << "zichuan" << endl;  //his problem is really tricky, i try to cout NULL and i fix bug just for this little error makes me very wordless
    
        string s5 = "ade";
        string s6 = "abcde";
        string res1 = MaxSubstring(s5, s6);
        cout << res1 << endl;
        cout << Maxsubsequence(s6, s5) << endl;
    
        string s7 = "accba";
        cout << isPalindrome(s7) << endl;
        return 0;
    }
  • 相关阅读:
    Spring MVC全局异常后返回JSON异常数据
    spring mvc 异常统一处理方式
    Duplicate fragment name ERROR Jetty Maven Plugin
    Android中自己定义组件和它的属性
    stl非变易算法(二)
    unix more命令
    g711u与g729比較编码格式
    MD5的加密和解密(总结)
    js 定义类对象
    润乾报表实现可反复分组报表及改进
  • 原文地址:https://www.cnblogs.com/LUO77/p/5759241.html
Copyright © 2011-2022 走看看