字符串编程练习(C++)

ex1 字符串变形

描述

对于一个长度为 n 字符串,我们需要对它做一些变形。

首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。

比如"Hello World"变形后就变成了"wORLD hELLO"。

数据范围: 1≤n≤10^{6} , 字符串中包括大写英文字母、小写英文字母、空格。

进阶:空间复杂度 O(n) , 时间复杂度 O(n)

输入描述:

给定一个字符串s以及它的长度n(1 ≤ n ≤ 10^{6})

返回值描述:

请返回变形后的字符串。题目保证给定的字符串均由大小写字母和空格构成。

 思路描述

这个题目对字符串的要求有两个:

1.字母的大小写互换

可以通过将字符s进行s-'a'+'A'将小写字母s变成大写字母,通过s-'A'+'a'将大写字母s变成小写字母

for(int i=0;i<n;i++){
    if(s[i]<='Z'&&s[i]>='A')//大写变小写
        res+=s[i]-'A'+'a';
    else if(s[i]>='a'&&s[i]<='z')//小写变大写
        res+=s[i]-'a'+'A';
    else res+=s[i];//空格照抄
}

2.字母内部单词反序

可以借助C++逆序函数reverse()分两步操作:

扫描二维码关注公众号,回复: 16009159 查看本文章

首先将整个字符串逆序,如:可将as bc变成cb sa;

然后进行对操作后的字符串,再进行以空格为分隔单位的逆序,如:可将cb sa变成bc as;

那么首先就是把每一个单词“认出来”,如认出“cb","sa",可通过一个for循环把字符串的初始位置记录下来,然后通过一个while循环找到单词的终点位置,即空格之前。

for(int i=0;i<n;i++){
    int j=i;//二次反转的起始位置
    while(j<n&&res[j]!=' ')//二次反转的终止位置
        j++;
    reverse(res.begin()+i, res.begin()+j);//二次反转
    i=j;
}

参考代码

#include <algorithm>
#include <string>
class Solution {
public:
   
    string trans(string s, int n) {
        // write code here
        if(n==0)
            return s;
        string res;
        for(int i=0;i<n;i++){
            if(s[i]<='Z'&&s[i]>='A')//大写变小写
                res+=s[i]-'A'+'a';
            else if(s[i]>='a'&&s[i]<='z')//小写变大写
                res+=s[i]-'a'+'A';
            else res+=s[i];//空格照抄
        }
        reverse(res.begin(),res.end());//整个反转
        for(int i=0;i<n;i++){
            int j=i;//二次反转的起始位置
            while(j<n&&res[j]!=' ')//二次反转的终止位置
                j++;
            reverse(res.begin()+i, res.begin()+j);//二次反转
            i=j;
        }
        return res;

    }
};

ex2 最长公共前缀

描述

给你一个大小为 n 的字符串数组 strs ,其中包含n个字符串 , 编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。

数据范围: 0≤n≤5000, 0≤len(​strs_{i})≤5000

进阶:空间复杂度 O(1),时间复杂度 O(n∗len)

示例

思路介绍

纵向遍历 

从第一个字符串开始,拿第一个字符串的第一个字符和下面的每一个字符串相比较,如果这一列字符都相同就接着比较第二列字符,一直到找到不同的字符或者是某一组字符串已经走到头为止。

for(int i=0;i<strs[0].size();i++){//比较第一个字符串的每一个字符
    for(int j=1;j<strs.size();j++){//纵向比较字符串
        if(strs[0][i]!=strs[j][i]||i==strs[j].size()){//比较后面的每一个字符串
            return strs[0].substr(0,i);//若字符不相同或者长度为最小则返回最长公共前缀
        }
    }
}

这里需要用到字符串分割函数substr(),该函数语法如下:

string substr (size_t pos, size_t len) const;

其中,pos表示要截取的子字符串的起始位置,len表示要截取的子字符串的长度。

还有一些其他的格式:

substr(string str, int a, int b);

str 是需要截取的字符串
a 截取字符串的开始位置
b 要截取的字符串的长度

substr(string str, int a) ;

a 可以理解为从第a个字符开始截取后面所有的字符串。

s.substr(pos, n)

返回一个string,包含s中从pos开始的n个字符的拷贝(pos的默认值是0,n的默认值是s.size() - pos,即不加参数会默认拷贝整个s)
若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾

代码参考

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        // write code here
        if(strs.size()==0)return "";//空串返回空值
        for(int i=0;i<strs[0].size();i++){//比较第一个字符串的每一个字符
            for(int j=1;j<strs.size();j++){//纵向比较字符串
                if(strs[0][i]!=strs[j][i]||i==strs[j].size()){//比较后面的每一个字符串
                    return strs[0].substr(0,i);//若字符不相同或者长度为最小则返回最长公共前缀
                }
            }
        }
        return strs[0];
    }
};

题目来源:

最长公共前缀_牛客题霸_牛客网 

猜你喜欢

转载自blog.csdn.net/m0_52124992/article/details/131796678
今日推荐