手撕字符串

作者: 熊大状 | 来源:发表于2018-08-08 10:33 被阅读0次

    基础知识:

    字符串长度: int length = s.length(); /length = s.size():不包括‘\0'

    【面试题49:把字符串转换成整数】String to Integer (atoi)

    题目:实现一个函数stringToInt,实现把字符串转换成整数这个功能,不能使用atoi或者其他类似的库函数。

    I think we only need to handle four cases:
    discards all leading whitespaces
    sign of the number
    overflow
    invalid input

    【面试题04:替换空格】

    题目:请实现一个函数,把字符串中的每个空格替换成"%20",例如“We are happy.”,则输出“We%20are%20happy.”。
    思路:先确定空格数量以及替换后字符串长度,然后从后往前遍历完成移动。时间复杂度O(n)。

    class Solution {
    public:
        void replaceSpace(char *str,int length) {
            int count=0; 
            int strlength =0;
            int i =0 ;
            while(str[i] != '\0'){
                if (str[i] == ' ' )
                    count++;
                strlength ++;
                i++;
            } 
            int newlength = strlength + 2*count;
            int p1 = strlength;
            int p2 = newlength;
            while( p1 >= 0 && p2>p1){
                if( str[p1--] == ' '){ 
                    str[p2--] = '0';  str[p2--] = '2'; str[p2--] = '%';
                }
                else
                    str[p2--] = str[p1--];
            }
        }
    };
    

    【面试题53:正则表达式匹配】Regular Expression Matching

    题目:请实现一个函数用来匹配包括'.'和 '*' 的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配。

    class Solution {
    public:
        bool isMatch(string s, string p) {  
            /*
            if 第二个字符为‘*’
                if 第一个字符相等
                    三种情况
                else
                    Match(sPos,pPos+2,s,p);
            else
                if 第一个字符相等
                    Match(sPos+1,pPos+1,s,p);
                else
                    false
            */
            return Match(0,0,s,p); 
        }
        bool Match(int sPos, int pPos, string &s, string &p) {
            //s结束,p结束,返回true
            if(sPos >= s.length() && pPos >= p.length())
                return true;
            //s未结束,p结束,返回false
            if(sPos < s.length() && pPos >= p.length())
                return false;
            //p未结束,不管s结束没,都有可能匹配成功
            if(pPos+1 < p.length() && p[pPos+1] == '*'){ 
                if(sPos<s.length() && (s[sPos] == p[pPos] || p[pPos] == '.'))
                    return Match(sPos,pPos+2,s,p)
                    ||Match(sPos+1,pPos+2,s,p)
                    ||Match(sPos+1,pPos,s,p);
                else
                    return Match(sPos,pPos+2,s,p);
            } 
            if(sPos<s.length() && (s[sPos] == p[pPos] || p[pPos] == '.'))
                return Match(sPos+1,pPos+1,s,p);    
            return false;
        } 
    };
    

    【面试题54:表示数值的字符串】

    题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
    思路:逐字符扫描,A.Be/EC,A、C有符号,B无符号。.前后不能都没数,e/E前后必有数。

    class Solution {
    public:
        bool isNumber(string s) {
            if(s.empty())
                return false;
            int pos = 0;
            //" 0.1 " => true,开头空格情况
            while(pos<s.length() && s[pos] == ' ')
                pos++;
            bool result = isInt(s,pos);
            if(pos<s.length() && s[pos] == '.'){ 
                if(++pos<s.length())
                    result = isUnsignedInt(s,pos) || result; 
                else
                    return result;
            }
            if(pos<s.length() && (s[pos] == 'e' || s[pos] =='E')){ 
                if(++pos<s.length())
                    result = isInt(s,pos) && result;
                else
                    return false;
            }
            //“1  ” =>true,结尾空格情况
            while(pos<s.length() && s[pos] == ' ')
                pos++;
            return result && (pos == s.length());
        }
        
        bool isInt(string &s, int &pos){ 
            if(s[pos] == '+' || s[pos] == '-')
                pos++;
            return isUnsignedInt(s,pos);
        }
        
        bool isUnsignedInt(string &s, int &pos){
            bool result = false;
            while(pos<s.length() && (s[pos]>='0' && s[pos]<='9')){
                pos++;
                result = true;
            } 
            return result;
        }
    };
    

    【面试题28:字符串的排列】

    题目: 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
    思路:回溯,先提二叉树的遍历,以二叉树中和为某一值的路径为例(路径以根节点开始,即对应前序遍历),从根节点一直左子树遍历到叶节点,每次将根节点压入vector,然后回溯到父节点并删除当前vector中节点,然后遍历其右子树。
    该问题类似多叉树,从左往右遍历字符,每个字符与之后所有字符(包括自己)交换,一直到最后一个字符,产生深度为串长度的多叉树。在进行回溯时需要通过循环递归(不像二叉树,只有左右子树,展开来写)。从左往右每个数分别跟之后的交换,然后处理下个数。递归结束的条件是处理到最后一个数字。ps:已经说不清楚了

    class Solution {
    public:
        vector<string> Permutation(string str) {
            vector<string>result;
            if(str.empty())
                return {};
            Permutation(str,0,result);
            //从小到大排序
            sort(result.begin(), result.end());
            return result;
        }
        void Permutation(string &str, int pos, vector<string> &result){ 
            //当遍历到最后一个字符是输出;类似于树的叶节点。
            //不同问题不同条件,如最短路径,统计路径小于最短,则更新路径;
            if(pos == str.length()-1)
                result.push_back(str);
            //循环接下来所有字符,类似多叉树,二叉树,只需循环左右子树。
            //当一次遍历到叶节点时,要回溯,需要swap回来,类似回到父节点,然后到下个叶节点。
            for(int i=pos; i<str.length();i++){
                if( pos == i || str[pos] != str[i]){
                    swap(str[pos],str[i]);
                    Permutation(str,pos+1,result);
                    swap(str[i],str[pos]); //返回父节点,恢复当一次交换               
                } 
            }  
            
        }
    };
    

    【面试题46:把数字翻译成字符串】 Decode Ways

    题目:给定一个数字,按照如下规则翻译成字符串:1翻译成“a”,2翻译成“b”...26翻译成“z”。一个数字有多种翻译可能,例如12258一共有5种,分别是bccfi,bwfi,bczi,mcfi,mzi。实现一个函数,用来计算一个数字有多少种不同的翻译方法。
    思路:动态规划,f(n) = f(n-1) + coef(n,n-1)*f(n-2),遇特殊情况:1)开头遇0,直接return;2)中间遇10或20,f(i) = f(i-2),否则return。

    //来自leetcode,0没有对应的码子,只有10和20能翻译
    class Solution {
    public:
        int numDecodings(string s) {
            if(s.empty()) 
                return 0; 
            int* counts = new int[s.length()]; 
            if(s[0] == '0') return 0;
            counts[0] = 1;
            
            for(int i=1;i<s.length();i++){    
                int digit1 = s[i] - '0'; 
                int digit2 = s[i-1] -'0';
                if(digit1 == 0){ 
                    if(digit2 == 1 || digit2 == 2){
                        counts[i] = (i == 1 ? 1: counts[i-2]);
                        continue; 
                    }//遇到10或20,counts[i] = counts[i-2]
                    else
                        return 0; 
                }  
                int coefficient = 0;
                int judgeDigit = digit2*10 + digit1;
                if(judgeDigit>=10 && judgeDigit<=26)
                    coefficient = 1;   
                counts[i] = counts[i-1] + coefficient * ( i == 1 ? 1: counts[i-2]);
            }
            int result = counts[s.length()-1];
            delete[] counts;
            return result;
            
        }
    };
    

    【面试题48:最长不含重复字符的子字符串】

    题目:请从字符串中找出一个最长的不包含重复字符串的子字符串,计算该最长子字符串的长度。假设字符串中只包含‘a’~‘z’的字符。
    思路:动态规划,f(i)定义为第i个字符结尾时最长子字符串的长度。关于f(i),分两种情况:1)第i个字符之前从未出现,或之前出现,但距离第i个字符的长度d大于f(i-1)(即上一个最长字符串长度)。这时f(i) = f(i-1)+1;2)之前出现,且位于f(i-1)中,这时f(i) = d,即被更新成以第i个字符结尾的最长串长度。

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            if(s.size() == 0) return 0;
            int position[128];
            for(int i = 0; i<128;i++)
                position[i]=-1;
            int curLength = 0;
            int maxLength = 0;
            for(int i =0; i<s.size();i++){
                int prePos = position[s[i]-' '];
                if(prePos<0 ||i-prePos>curLength)
                    curLength++;
                else{
                    curLength = i-prePos;
                }
                position[s[i]-' ']= i; //更新字符坐标
                if(curLength>maxLength)
                    maxLength = curLength;
            }
            return maxLength;
        }
    };
    

    【面试题50:第一个只出现一次的字符】First Unique Character in a String

    题目:请实现一个函数用来找出字符流中第一个只出现一次的字符。
    思路:map计数

    class Solution {
    public:
        int firstUniqChar(string s) {
            map<char,int>mapping;
            for(int i = 0 ; i< s.size();i++){
                mapping[s[i]]++;
            }
            for(int i = 0; i < s.size(); i++){
                if(mapping[s[i]]==1)
                    return i;
            }
            return -1;
        }
    };
    

    Buddy Strings

    题目:给定字符串A和B,判断A是否仅交换两个字符能与B相等。
    思路:遍历A,找到第一个与B不同的字符,然后接着找到第二个与B不同的字符,然后交换两个字符,判断是否相等。时间复杂度O(n)。ps:存在A==B的特殊情况,单独考虑。

    class Solution {
    public:
        bool buddyStrings(string A, string B) {
            if (A.size() != B.size())  return false;
            if(A == B) return isDifferent(A);//如A等于B,若A中有相同字符,即true,否则false;
            int pos1 = 0;
            while(pos1<A.size() && (A[pos1] == B[pos1]))
                pos1++;
            int pos2 = pos1+1;
            while(pos2<A.size() && (A[pos2] == B[pos2]))
                pos2++;
            int temp = A[pos1];
            A[pos1] = A[pos2];
            A[pos2] = temp;
            return A==B? true:false;
        }
        bool isDifferent(string A){
            map<char,int>count;
            for(int i =0 ; i<A.size();i++){
                count[A[i]]++;
                if(count[A[i]] >1)
                    return true;
            }
            return false;
        }
    };
    

    Construct String from Binary Tree

    题目:You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way.
    思路:二叉树的先序遍历,同时需要考虑括号,左子树必须加括号,右子树非空时加括号。

    Example 1:
    Input: Binary tree: [1,2,3,4]
           1
         /   \
        2     3
       /    
      4     
    
    Output: "1(2(4))(3)"
    
    Example 2: 如无左节点,用null,空().
    Input: Binary tree: [1,2,3,null,4]
           1
         /   \
        2     3
         \  
          4 
    
    Output: "1(2()(4))(3)"
    
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        string tree2str(TreeNode* t) {
            string res ;
            ConstructStr(t,res);
            return res; 
        }
        void ConstructStr(TreeNode* t, string &res){
            if(!t) return;
            res += to_string(t->val);
            if(!t->left && !t->right) return; 
            
            res += '(';
            ConstructStr(t->left,res);
            res += ')';
            
            if( !t->right ) return; //若无右子树,则返回。与无左子树不同。
            res += '(';
            ConstructStr(t->right,res);
            res += ')'; 
        }
    };
    

    Roman to Integer

    Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

    创建一个map: map<char,int>mapping = {{},{},{}};
    该字符值大于下一字符值就累加,小于累减。

    class Solution {
    public:
        int romanToInt(string s) {
            int sum =0;
            map<char,int>mapping={
                {'I',1},
                {'V',5},
                {'X',10},
                {'L',50},
                {'C',100},
                {'D',500},
                {'M',1000} 
            };
            for(int i =0; i < s.length()-1; i++){
                if(mapping[s[i]]>=mapping[s[i+1]])
                    sum += mapping[s[i]];
                else
                    sum -= mapping[s[i]];
            }
            sum += mapping[s[s.length()-1]];
            return sum;
        }
    };
    

    Valid Parentheses

    题目:Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

    [],{},(),成对出现,采用栈的数据结构,先进后出。先进栈的符号之后配对。
    判断条件:空栈,即所有左开口符号均配对成功。不成立条件:1)空栈时遇上右开口;2)非空栈时,遇上右开口与出栈的左开口不配对。

    class Solution {
    public:
        bool isValid(string s) {
            map<char,char>mapping = {{'(',')'},{'{','}'},{'[',']'}};
            stack<char>pareStack;
            for(int i = 0; i<s.size(); i++){
                if(s[i] == '(' || s[i] == '{' ||s[i] == '[')
                    pareStack.push(s[i]);
                else{
                    if(pareStack.empty())
                        return false;
                    if(s[i] != mapping[pareStack.top()])
                        return false;
                    pareStack.pop();
                }
            } 
            return pareStack.empty();
        }
    };
    

    Add Binary

    题目:Given two binary strings, return their sum (also a binary string).
    The input strings are both non-empty and contains only characters 1 or 0.
    Example 2:
    Input: a = "1010", b = "1011"
    Output: "10101"
    思路: 数字字符转数字:s[i]-'0'; 数字转字符:to_string

    class Solution {
    public:
        string addBinary(string a, string b) {
            int Pa = a.size()-1;
            int Pb = b.size()-1;
            int overflow = 0;
            string addStr = "";
            while(Pa>= 0 || Pb>= 0){
                int aStr = Pa>-1 ? a[Pa]-'0': 0;
                int bStr = Pb>-1 ? b[Pb]-'0': 0;
                addStr += to_string((aStr+bStr+overflow)%2);
                overflow = (aStr+bStr+overflow)/2;
                Pa--;Pb--;
            }
            if(overflow)
                addStr += '1';  
            changeChars(addStr,0,addStr.size()-1);
            return addStr;
        }
        void changeChars(string &s, int begin, int end){
            while(begin<end){
                char temp = s[begin]; 
                s[begin] = s[end];
                s[end] = temp;
                begin++;end--;
            }
        }
    };
    

    Longest Common Prefix

    题目:写一个函数,找到数组中字符串元素的最长公共字首,如无公共字符,返回空字符串。
    思路:先确定前两个字符串的公共字首,然后将公共字首与第三个比较,以此类推,确定最后的最长公共字首。

    class Solution {
    public:
        string longestCommonPrefix(vector<string>& strs) {
            if (strs.empty()) return "";
            string samestr = strs[0];
            for (int i =1;i<strs.size();i++){
                samestr = JudgeSameStr(samestr, strs[i]);  
                if(samestr.empty()) return samestr;
            }
            return samestr;
        }
        string JudgeSameStr(string str1,string str2){ 
            string samestr ="";
            for(int j=0; j<str1.size();j++){
                if(j>str2.size()-1 || str1[j]!=str2[j]) return samestr;
                samestr += str1[j];
            } 
            return samestr;
        }
    };
    

    Reverse Words in a String III

    题目:Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order.
    Example 1:
    Input: "Let's take LeetCode contest"
    Output: "s'teL ekat edoCteeL tsetnoc"
    思路:分两部分:1)确定每个word的起始点;2)每个word进行reverse。
    PS:判断word结尾的两种情况,1)空格 ;2)串尾

    class Solution {
    public:
        string reverseWords(string s) {
            int begin = 0;
            int end = 0;
            while(end<s.size()){
                if(s[end] == ' '){
                    changeChars(s,begin,--end);
                    begin = end = end+2;
                } 
                else if(end == s.size()-1){
                    changeChars(s,begin,end++);
                }
                else{
                    end++;
                }
            }
            return s;
            
        }
        void changeChars(string &s, int begin, int end){
            while(begin<end){
                char temp = s[begin]; 
                s[begin] = s[end];
                s[end] = temp;
                begin++;end--;
            }
        }
    }; 
    
    void TransStr(string &str, int begin, int end){
        if(!str.empty()){
            while(begin<end)
                swap(str[begin++],str[end--]);
        }
    }
    int main(){
        string str;
        while(getline(cin,str)){
            if(str.empty() || str.length()>100)
                return 0;
            TransStr(str,0,str.length()-1);
            int begin = 0;
            int end = 0;
            while(end < str.length()){
                if(str[begin] == ' '){
                    begin++;
                    end++;
                }
                while(end < str.length() && str[end] != ' ')
                    end++;
                TransStr(str,begin,end-1);
                begin = end; 
            }
            for(int i=0; i<str.length();i++)
                cout<<str[i];
        }
        return 0;
    }
    

    Longest Valid Parentheses

    题目:Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring。
    思路:由于括号先进后出规律,采用栈的结构,我们需要通过计算坐标找出最长子串的长度,所以栈中存放的是括号在主串的位置。计算规律:一次匹配意味着一次出栈,计算此时坐标与栈顶的距离,即为此时的有效子串长度。注意栈顶元素的意义,向前未匹配有效的坐标。如果没有出栈条件,均入栈。一种情况是空栈,意味着此时坐标之前的串均有效。

    class Solution {
    public:
        int longestValidParentheses(string s) {
            stack<int>sequence;
            int max = 0;
            for(int i=0; i<s.size(); i++){ 
                if(s[i] == ')' && !sequence.empty() && s[sequence.top()] == '('){
                    sequence.pop();
                    int length = sequence.empty()? i+1: i-sequence.top();
                    max = std::max(length, max);
                }
                else 
                    sequence.push(i);
            }
            return max;
        }
    };
    

    Push Dominoes

    题目:用字符定义骨牌的状态,‘L’代表向左倒,‘R’代表向右倒,‘.’代表让为站立。例如".L.R...LR..L..",输出为"LL.RR.LLRRLL.."。
    思路:考虑清楚三种情况:1)RL形成区间,2)从左往右,只有L,3)从左往右,只有R。
    例如...L..R...R...L...L...R....

    class Solution {
    public:
        string pushDominoes(string str) {
            string changeStr;
            for (int i = 0; i<str.length(); i++)
                changeStr += ".";
            int pos = 0;
            int nextRight = -1; 
            while (pos<str.length()) {
                if (str[pos] == 'R') {
                    if (nextRight == -1)
                        nextRight = pos;//遇到R且前面没有R
                    else {
                        //遇到R且前面有R
                        for (int i = nextRight; i < pos; i++)
                            changeStr[i] = 'R';
                        nextRight = pos;//更新R的位置。
                    } 
                }
                else if (str[pos] == 'L') {
                    if (nextRight == -1) { 
                        changePos(changeStr, -1, pos);
                    }//遇到L且前面没有R状态(这个状态是指可以形成RL区间的,而不是已经右倒状态)
                    else {
                        changePos(changeStr, nextRight, pos);
                        nextRight = -1;
                    }//遇到L且前面有R状态,形成RL区间
                }
                pos++;
            }
            if(nextRight != -1)
                changePos(changeStr, nextRight, str.length()); 
            return changeStr;
        }
        
        void changePos(string &changeStr, int right, int left) {
        int i = left;
        while(right<0 && i >= 0 && changeStr[i] == '.') { 
            changeStr[i--] = 'L'; 
        }//L前面没有R,向前置‘L’一直到非‘.’。
        i = right;
        while(left >= changeStr.length() && i<changeStr.length()) { 
                changeStr[i++] = 'R'; 
        }//
        if (right >= 0 && left < changeStr.length()) {
            int middle = (right + left) / 2;
            for (int i = right; i<middle; i++)
                changeStr[i] = 'R';
            if ((right + left) % 2 == 1)
                changeStr[middle] = 'R';
            for (int i = middle + 1; i <= left; i++)
                changeStr[i] = 'L';
        } 
    } 
    };
    

    华为-简单错误记录

    问题描述:个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
    处理:
    1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
    2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
    3.输入的文件可能带路径,记录文件名称不能带路径

    输入描述:

    一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
    文件路径为windows格式
    如:E:\V1R2\product\fpgadrive.c 1325

    输出描述:

    将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1
    结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。
    如果超过8条记录,则只输出前8条记录.
    如果文件名的长度超过16个字符,则只输出后16个字符

    示例1 
    ## 输入 
    E:\V1R2\product\fpgadrive.c 1325
    ## 输出
    fpgadrive.c 1325 1
    
    
    #include<iostream>
    #include<vector>
    #include<sstream>
    #include<string>
    using namespace std;
     
    int str2num(string s)
    {
        int num;
        stringstream ss(s);
        ss >> num;
        return num;
    }
    int main() {
        string str;
        vector<string>filenames;//存放文件名(文件名称和行号)
        vector<int>count;//对应文件的数量
        while(getline(cin,str)){
            if(str.length() == 0)
                break;
            unsigned int idx = str.rfind('\\');
            string filename = str.substr(idx+1);
            bool exist = false;//记录文件是否存在
            for(int i=0;i<filenames.size();i++){
                if(filenames[i] == filename){
                    count[i]++;
                    exist = true;
                    break;
                }
            }
            if(!exist){//如果未出现过,就记录。
                filenames.push_back(filename);
                count.push_back(1);
            }
        }
        //直接插入排序
        for(int i=1; i<=filenames.size(); ++i){
            for(int j=i; j > 0; --j){
                if(count[j] > count[j -1]){
                    swap(count[j],count[j-1]);
                    swap(filenames[j],filenames[j-1]);
                }
            }
        }
        //按要求打印前8条记录
        for(unsigned int k=0; k<8 && k<filenames.size();k++){
            unsigned int blankIdx = filenames[k].rfind(' ');
            string file = filenames[k];
            if(blankIdx >16)//文件名称超过规定长度。
                file = file.erase(0,blankIdx-16);
            cout<<file<<" "<<count[k]<<endl;;
        }
        return 0;
    }
    

    string的操作:
    s.substr(pos,n); 返回一个string,包含s中从pos开始的n个字符的拷贝。
    s.rfind(ch): 找到最后出现ch的位置。
    s.find(ch): 找到第一次出现ch的位置。
    s.erase(pos,len)

    华为-简单错误记录

    问题描述:老师想知道从某某同学当中,分数最高的是多少,现在请你编程模拟老师的询问。当然,老师有时候需要更新某位同学的成绩.

    输入描述:

    输入包括多组测试数据。
    每组输入第一行是两个正整数N和M(0 < N <= 30000,0 < M < 5000),分别代表学生的数目和操作的数目。
    学生ID编号从1编到N。
    第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩
    接下来又M行,每一行有一个字符C(只取‘Q’或‘U’),和两个正整数A,B,当C为'Q'的时候, 表示这是一条询问操作,他询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少
    当C为‘U’的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。

    输出描述:

    对于每一次询问操作,在一行里面输出最高成绩.

    交换两个同类型元素,可以直接使用swap函数;
    取最大值可直接使用std::max;
    
    示例1
    输入
    5 7
    1 2 3 4 5
    Q 1 5
    U 3 6
    Q 3 4
    Q 4 5
    U 4 5
    U 2 9
    Q 1 5
    输出
    5
    6
    5
    9
    
    #include<iostream>
    using namespace std;
      
    int main(){
        int n,m;
        while(cin>>n>>m){
            int sorce[n];char op;int A,B;
            for(int i=0; i<n; i++)
                cin>>sorce[i]; 
            while(m--){
                cin>>op>>A>>B;
                if( op == 'Q'){
                    int max = 0;
                    if(A>B) swap(A,B);
                    for(int i=A-1; i<B; i++)
                       max = std::max(max,sorce[i]);
                    cout<<max<<endl;
                }
                else if(op == 'U')
                    sorce[A-1] = B;
            }
        }
         
        return 0;
    }
    

    好未来-删除公共字符

    题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”

    #include<iostream>
    #include<string>
    using namespace std;
      
    int main(){
        string orgStr;
        string delStr;
        while(getline(cin,orgStr)){
            getline(cin,delStr);
            for(int i=0; i<delStr.length();i++){
                for (int j=0; j<orgStr.length();j++){
                    if(orgStr[j] == delStr[i])
                        orgStr = orgStr.erase(j,1);
                }
            }
            cout<<orgStr<<endl;
        }
        return 0;
    }
    

    好未来-字符串组合

    题目:固定数组:{0,1,2,3,4,5,6,7,8,9},输入布尔数组:{0,1,1,1,1,1,1,1,1,0} ,0表示对应数组的下标元素可出现亦可不出现,1则表示必须出现。
    输出所有可能的组合,最终结果按升序排序。
    思想:回溯,深度遍历,遇0多一种情况。

    #include<iostream>
    #include<vector>
    #include<string>
    #include<algorithm>
    
    using namespace std;
    
    void Collect(vector<int>& isIndex, string str, int pos, vector<string>& result) {
        if (pos == isIndex.size()) {
            result.push_back(str);
            return;
        }//遍历到最后一个值时,结束递归。
        if (isIndex[pos] == 0)//遇0,多一种情况,直接跳过当前值。
            Collect(isIndex, str, pos + 1, result);
        //不管0/1,这种情况都存在,储存当前值
        str += to_string(pos);
        Collect(isIndex, str, pos + 1, result);
    }
    
    int main() {
        vector<int>isIndex;  
        int a;
        while (cin >> a)
            isIndex.push_back(a); 
        vector<string>result;
        string str;
        Collect(isIndex, str, 0, result);
        sort(result.begin(), result.end());
        for (int i = 0; i< result.size(); i++)
            cout << result[i] << endl;  
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:手撕字符串

        本文链接:https://www.haomeiwen.com/subject/uhstbftx.html