• LintCode刷题指南:字符串处理(C++,Python)


    题目:两个字符串是变位词

    题目难度:简单

    题目描述:

    写出一个函数 anagram(s, t) 判断两个字符串是否可以通过改变字母的顺序变成一样的字符串。

    解题思路:

    C++:引入哈希的思维,这道题就迎刃而解了。

    C++ Code:

    class Solution {
    public:
        /**
         * @param s: The first string
         * @param b: The second string
         * @return true or false
         */
        bool anagram(string s, string t) {
            // write your code here
            int dic[58];
            for (int i = 0; i < 58; i++)
                dic[i] = 0;
            for ( int i = 0; i < s.size(); i++ )
            {
                if (s[i] == ' ')
                    continue;
                int index = s[i] - 'A';
                dic[index]++;
            }
            for ( int i = 0; i < t.size(); i++ )
            {
                if (t[i] == ' ')
                    continue;
                int index = t[i] - 'A';
                dic[index]--;
            }
            for ( int i = 0; i < 58; i++ )
            {
                if (i==57 && dic[i]==0)
                    return true;
                if (dic[i] == 0)
                    continue;
                else
                    return false;
            }
        }
    };

    Python:利用Python的list()方法与sort()方法就可以成功地解决这道问题。

    Python Code:

    class Solution:
        """
        @param s: The first string
        @param b: The second string
        @return true or false
        """
        def anagram(self, s, t):
            # write your code here
            a = list(s)
            b = list(t)
            a.sort()
            b.sort()
            if a == b:
                return True
            else:
                return False

    题目:比较字符串

    题目难度:简单

    题目描述:

    比较两个字符串A和B,确定A中是否包含B中所有的字符。字符串A和B中的字符都是大写字母。

    解题思路:

    C++:与第一道题几乎一样的哈希思路。

    C++ Code:

    class Solution {
    public:
        /**
         * @param A: A string includes Upper Case letters
         * @param B: A string includes Upper Case letter
         * @return:  if string A contains all of the characters in B return true
         *           else return false
         */
        bool compareStrings(string A, string B) {
            // write your code here
            int dic[26];
            int index;
            for (int i = 0; i < 26; i++)
                dic[i] = 0;
            for (int i = 0; i < A.size(); i++) {
                if (A[i] == ' ')
                    continue;
                index = A[i] - 'A';
                dic[index]++;
            }
            for (int i = 0; i < B.size(); i++) {
                if (B[i] == ' ')
                    continue;
                index = B[i] - 'A';
                dic[index]--;
            }
            for (int i = 0; i < 26; i++) {
                if (dic[i] < 0)
                    return false;
                if (i == 25 && dic[i] >= 0)
                    return true;
            }
           
        }
    };

    Python:利用Python中的list()方法与index()方法,将B中的字符在A中逐个比对,每一次将A中对应的字符删除,循环这个过程。

    Python Code:

    class Solution:
        """
        @param A : A string includes Upper Case letters
        @param B : A string includes Upper Case letters
        @return :  if string A contains all of the characters in B return True else return False
        """
        def compareStrings(self, A, B):
            # write your code here
            a = list(A)
            b = list(B)
            for n in b:
                if n in a:
                    index = a.index(n)
                    del a[index]
                    continue
                else:
                    return False
            return True

    题目:字符串查找

    题目难度:简单

    题目描述:

    对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回-1。

    解题思路:

    C++:通过一个简单的二层循环嵌套进行比对即可解决此题,需要注意的是处理NULL情况。

    C++ Code:

    class Solution {
    public:
        /**
         * Returns a index to the first occurrence of target in source,
         * or -1  if target is not part of source.
         * @param source string to be scanned.
         * @param target string containing the sequence of characters to match.
         */
        int strStr(const char *source, const char *target) {
            // write your code here
            if (source == NULL || target == NULL)
                return -1;
            int index, i;
            int ssize = strlen(source);
            int tsize = strlen(target);
            if (ssize < tsize)
                return -1;
            for (index = 0; index <= ssize - tsize; index++)
            {
                for (i = 0; i <= tsize - 1; i++)
                {
                    if (source[i + index] != target[i])
                        break;
                }
                if (i == tsize)
                        return index;
            }
            return -1;
        }
    };

    Python:和C++的思路是大致相同的,但是可以运用Python中的字符串截取方法,代码比C++更简短,同样需要注意处理null情况(Python中为None)。

    Python Code:

    class Solution:
        def strStr(self, source, target):
            # write your code here
            index = 0
            if source is None or target is None:
                return -1
            if len(source) < len(target):
                return -1
            if source == target:
                return 0
            while index <= len(source) - len(target):
                if source[index: index + len(target)] == target:
                    return index
                if index == len(source) - len(target) and source != target:
                    return -1
                index += 1

    题目:乱序字符串

    题目难度:中等

    题目描述:

    给出一个字符串数组S,找到其中所有的乱序字符串(Anagram)。如果一个字符串是乱序字符串,那么他存在一个字母集合相同,但顺序不同的字符串也在S中。

    解题思路:

    C++:先将字符串数组中的字符串都进行排序,然后运用unordered_map的特性来解决问题,值得一提的是,如果在排序方法中运用O(n^2)的方法,是会判定超时的。

    C++ Code:

    class Solution {
    public:
        /**
         * @param strs: A list of strings
         * @return: A list of strings
         */
        void sort(string &input) {
            int count[26];
            int index;
            for (int i = 0; i < 26; i++) {
                count[i] = 0;
            }
            for (int i = 0; i < input.length(); i++) {
                index = input[i] - 'a';
                count[index]++;
            }
            input = "";
            for (int i = 0; i < 26; i++) {
                for (int j = 0; j < count[i]; j++) {
                    input += (char)('a' + i);
                }
            }
        }

        vector<string> anagrams(vector<string> &strs) {
            // write your code here
            vector<string> result;
            vector<string> mystrs = strs;
            for (int i = 0; i < mystrs.size(); i++) {
                sort (mystrs[i]);
            }
            unordered_map<string, int> dic;
            for (int i = 0; i < mystrs.size(); i++) {
                if (dic.find(mystrs[i]) == dic.end())
                    dic[mystrs[i]] = 1;
                else
                    dic[mystrs[i]]++;
            }
            for (int i = 0; i < mystrs.size(); i++) {
                if (dic[mystrs[i]] == 1)
                    continue;
                else
                    result.push_back(strs[i]);
            }
            return result;
            }
    };

    Python:在思路上和C++解法并没有太大区别,但是由于Python语言本身的一些特性,可以让代码量相较于C++版本的解法大幅减少,运用Python中的字典类型与sorted()方法可以很简洁地解出这道题。(注:运用sort()方法也可以,但是sort()方法本身会改变list的值,会让代码量略微增多)

    Python Code:

    class Solution:
        # @param strs: A list of strings
        # @return: A list of strings
        def anagrams(self, strs):
            # write your code here
            dic = {}
            result = []
            for string in strs:
                sortedstr = "".join(sorted(string));
                dic[sortedstr] = [string] if sortedstr not in dic else dic[sortedstr] + [string]
            for key in dic:
                result += dic[key] if len(dic[key]) >= 2 else []
            return result

    题目:最长公共子串

    题目难度:中等

    题目描述:

    给出两个字符串,找到最长公共子串,并返回其长度。

    解题思路:

    C++:这道题固然是可以用遍历的方法硬解出来的,但是那样的复杂度是非常不令人满意的,这里比较好的方法是运用动态规划的思想来解答,假设在求最长公共子串对的过程中,A中的子串中最后一个字符的位置为i,B中的子串中最后一个字符的位置为j,实际上就可以把“分别以A[i]与B[j]作为最后一个字符时最长公共字串的长度是多少”当作动态规划中的子问题,设分别以A[i]与B[j]作为最后一个字符时最长公共字串的长度为longestCommonSubstring[i][j],不难得出longerstCommonSubstring[i][j] = (A[i] == B[j] ? longestCommonSubstring[i - 1][j - 1] + 1 : 0)的推导关系,这样就可以以动态规划的思想来解答该题了。

    C++ Code:

    class Solution {
    public:
        /*
         * @param A: A string
         * @param B: A string
         * @return: the length of the longest common substring.
         */
        int longestCommonSubstring(string A, string B) {
            // write your code here
            if (A == "" || B == "")
                return 0;
            int sizeA = A.size();
            int sizeB = B.size();
            int longest = 0;
            vector<vector<int> > list(sizeA, vector<int>(sizeB, 0));
            int initIndex = 0;
            for (int i = 0; i < sizeB; i++) {
                list[initIndex][i] = (A[initIndex] == B[i] ? 1 : 0);
            }
            for (int i = 0; i < sizeA; i++) {
                list[i][initIndex] = (A[i] == B[initIndex] ? 1 : 0);
            }
            for (int i = 1; i < sizeA; i++) {
                for (int j = 1; j < sizeB; j++) {
                    list[i][j] = (A[i] == B[j] ? list[i - 1][j - 1] + 1 : 0);
                }
            }
            for (int i = 0; i < sizeA; i++) {
                for (int j = 0; j < sizeB; j++) {
                    if (longest < list[i][j])
                        longest = list[i][j];
                }
            }
            return longest;
        }
    };

    Python:解题思路与C++版本相同,直接贴代码。

    Python Code:

    class Solution:
        """
        @param: A: A string
        @param: B: A string
        @return: the length of the longest common substring.
        """
        def longestCommonSubstring(self, A, B):
            # write your code here
            if (len(A) == 0 or len(B) == 0):
                return 0
            longest = 0
            list = [[0 for i in range(len(B))] for j in range(len(A))]
            for i in range(len(B)):
                if A[0] == B[i]:
                    list[0][i] = 1
            for i in range(len(A)):
                if A[i] == B[0]:
                    list[i][0] = 1
            for i in range(1, len(A)):
                for j in range(1, len(B)):
                    if A[i] == B[j]:
                        list[i][j] = list[i - 1][j - 1] + 1
            for i in range(len(A)):
                for j in range(len(B)):
                    if list[i][j] > longest:
                        longest = list[i][j]
            return longest

    题目:最长公共前缀

    题目难度:中等

    题目描述:

    给k个字符串,求出他们的最长公共前缀(LCP)。

    解题思路:

    C++:没有什么难点,注意判断几个特殊情况即可,例如传入的字符串个数为0,或传入的字符串中存在长度为0的字符串。

    C++ Code:

    class Solution {
    public:
        /*
         * @param strs: A list of strings
         * @return: The longest common prefix
         */
        string longestCommonPrefix(vector<string> strs) {
            // write your code here
            string LCP;
            if (strs.size() == 0)
                return LCP;
            for (int i = 0; i < strs[0].length(); i ++) {
                for (int j = 1; j < strs.size(); j++) {
                    if (strs[j] == "")
                        return LCP;
                    if (strs[j].length() < i + 1)
                        return LCP;
                    if (strs[0][i] != strs[j][i])
                        return LCP;
                }
                LCP += strs[0][i];
            }
            return LCP;
        }
    };

    Python:与C++的解题思路一致,直接上代码:

    Python Code:

    class Solution:
        """
        @param: strs: A list of strings
        @return: The longest common prefix
        """
        def longestCommonPrefix(self, strs):
            # write your code here
            if len(strs) == 0:
                return ""
            if len(strs) == 1:
                return strs[0]
            minlength = min([len(s) for s in strs])
            for i in range(minlength):
                for j in strs:
                    if strs[0][i] != j[i]:
                        return strs[0][0: i]
            return strs[0][0: minlength]

    题目:转换字符串到整数

    题目难度:困难

    题目描述:

    实现atoi这个函数,将一个字符串转换为整数。如果没有合法的整数,返回0。如果整数超出了32位整数的范围,返回INT_MAX(2147483647)如果是正整数,或者INT_MIN(-2147483648)如果是负整数。

    解题思路:

    C++:此题的难点主要在于需要考虑很多种情况,非常容易遗漏,需要考虑的情况有:传入的字符串长度为零;字符串前几位为‘ ’;正负号情况;字符串中间出现的非数字;数字大于INT_MAX或小于INT_MIN。

    C++ Code:

    class Solution {
    public:
        /*
         * @param str: A string
         * @return: An integer
         */
        int atoi(string str) {
            // write your code here
            int index = 0;
            while (str[index] == ' ')
                index++;
            int number = 0, sign = 1;
            if (str[index] == '-' || str[index] == '+') {
                sign = str[index] == '-' ? -1: 1;
                index++;
            }
            for (; index < str.size(); index++) {
                if (str[index] >= '0' && str[index] <= '9') {
                    if (number > INT_MAX / 10 || (number == INT_MAX / 10 && str[index] - '0' > 7))
                        return sign == 1 ? INT_MAX: INT_MIN;
                    number = number * 10 + (str[index] - '0');
                }
                else
                    return number * sign;
            }
            return number * sign;
        }
    };

    Python:解题思路与C++一致。

    Python Code:

    class Solution:
        """
        @param: str: A string
        @return: An integer
        """
        def atoi(self, str):
            # write your code here
            index, number, sign = 0, 0, 1
            intmax, intmin = (1 << 31) - 1, -1 << 31
            if str == "":
                return number
            while str[index] == ' ':
                index += 1;
            if str[index] == '-' or str[index] == '+':
                if str[index] == '-':
                    sign = -1
                index += 1
            while index < len(str) and str[index] >= '0' and str[index] <= '9':
                if number > intmax / 10 or (number == intmax / 10 and ord(str[index]) - ord('0') > 7):
                    return intmax if sign == 1 else intmin
                number = number * 10 + ord(str[index]) - ord('0')
                index += 1
            return number * sign

    备注:本人非常乐意分享我的文章,转载请注明我的博客地址:http://www.cnblogs.com/matthewli/与原文地址:http://www.cnblogs.com/matthewli/p/7376738.html,谢谢!

  • 相关阅读:
    start with connect by prior 递归查询用法(二)
    start with connect by prior 递归查询用法(一)
    oracle之spool详细使用总结
    关于ETL面试相关
    ETL常用的三种工具介绍及对比Datastage,Informatica和Kettle
    Oracle执行计划详解
    随机函数的使用(DBMS_RANDOM)
    oracle中的替换函数replace和translate函数
    ces
    文章11
  • 原文地址:https://www.cnblogs.com/matthewli/p/7376738.html
Copyright © 2020-2023  润新知