两个针对字符串句子题目的模板

本文介绍了如何使用模板来解答LeetCode上涉及字符串处理的题目,包括:反转字符串中的单词、反转单词顺序、截断句子等。通过解题思路和模板代码,帮助读者理解和解决这类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解题思路

  1. 先将句子中所有的字符串取出放入字符串数组中。
  2. 再对数组中的字符串进行操作后重新连接

遍历句子取字符串的思路:将遇到的字符放进临时字符串中,遇得空格或者标点符号,就将临时字符串放进字符串数组中,并且将临时字符串清空。

模板代码

一、字符串前后有空格

s +=" ";//在字符串最后位置加上空格,这样最后一个字符串就不会遗漏
string temp = "";//创建临时字符串
vector<string> res;//存放字符串数组
int main()
{
	for (char ch : s)//遍历字符串
	{
		if (ch == ' ')//遇见空格或者这里也可以根据题目要求,将空格改标点符号
		{
			//遇见空格,代表字符串s中的一个单词已经全部存储在临时字符串中
			if (!temp.empty())//临时字符串非空
			{
				//将临时字符串存储在字符串数组中
				res.push_back(temp);
				temp.clear();//将临时字符串清空,方便存入字符串s中下一个单词
			}			
		}
		else//临时字符串是空,代表已经遍历到字符串最后一个位置了。
		{
			temp += ch;
		}
	}
}

二、字符串前后没有空格

s += " ";
	string temp = "";
	vector<string> res;
	for (char ch : s)
	{
		if (ch == ' ')
		{
			res.push_back(temp);
			temp.clear();
		}
		else
		{
			temp += ch;
		}
	}

有关字符串的题目

最后一个单词的长度
反转字符串中的单词
反转单词顺序
截断句子
字符串中不同整数的数目
最常见的单词
山羊拉丁文
检查单词是否为句子中其他单词的前缀
重新排列单词间的空格
将句子排序

解题方法:

最后一个单词的长度
题目描述:给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。
从题目描述中我们可以看出,该题目可以直接套用模板1,返回字符串数组尾的元素长度。

class Solution {
public:
    int lengthOfLastWord(string s) {
        s+=' ';
        string temp;
        vector<string> res;
        for(char ch:s)
        {
            if(ch==' ')
            {
                if(!temp.empty())
                {
                    res.push_back(temp);
                    temp.clear();
                }
               
            }
            else
            {
                temp+=ch;
            }
        }
        if(res.empty())return 0;
        return res.back().size();

    }
};

反转字符串中的单词
题目描述:给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
我们根据题目要求可以判断出,我们只需要将字符串中所有单词的字母顺序颠倒即可。

class Solution {
public:
    string reverseWords(string s) {
        s+=' ';
        string temp="";
        vector<string>res;
        for(char ch:s)
        {
            if(ch==' ')
            {
                res.push_back(temp);
                temp.clear();
            }
            else
            {
                temp+=ch;
            }
        }
        s.clear();//将原字符串清空
        for(auto&str:res)
        {
            reverse(str.begin(),str.end());
            s+=str+' ';//将单词用' '空格隔开
        }
        //执行在这里,意味着将所有单词全部反转,但是最后一个单词多了一个空格
        s.pop_back();//将最后一个空格删除
        return s;
    }

反转单词顺序
题目描述:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。

class Solution {
public:
    string reverseWords(string s) {
        if(s.empty())return "";
        s+=" ";
        string temp="";
        vector<string>res;
        for(char ch:s)
        {
            if(ch==' ')
            {
                if(!temp.empty())
                {
                    res.push_back(temp);
                    temp.clear();
                }
            }
            else
            {
                temp+=ch;
            }
        }
        s.clear();
        reverse(res.begin(),res.end());
        for(auto&str:res)
        {
            s+=str+' ';
        }
        s.pop_back();
        return s;

    }
};

截断句子
题目描述:句子 是一个单词列表,列表中的单词之间用单个空格隔开,且不存在前导或尾随空格。每个单词仅由大小写英文字母组成(不含标点符号)给你一个句子 s​​​​​​ 和一个整数 k​​​​​​ ,请你将 s​​ 截断 ​,​​​使截断后的句子仅含 前 k​​​​​​ 个单词。返回 截断 s​​​​​​ 后得到的句子。
输入:s = “Hello how are you Contestant”, k = 4
输出:“Hello how are you”
解释:
s 中的单词为 [“Hello”, “how” “are”, “you”, “Contestant”]
前 4 个单词为 [“Hello”, “how”, “are”, “you”]
因此,应当返回 “Hello how are you”
示例中没有前置或者后置空格,所以用模板二。

class Solution {
public:
    string truncateSentence(string s, int k) {
        s+=" ";
        string temp="";
        vector<string>res;
        for(char ch:s)
        {
            if(ch==' ')
            {
                res.push_back(temp);
                temp.clear();
            }
            else
            {
                temp+=ch;
            }
        }
        s.clear();
        for(int i=0;i<k;++i)
        {
            s+=res[i]+' ';
        }
        s.pop_back();
        return s;

    }
};

字符串中不同整数的数目
题目描述:给你一个字符串 word ,该字符串由数字和小写英文字母组成。
请你用空格替换每个不是数字的字符。例如,“a123bc34d8ef34” 将会变成 " 123 34 8 34" 。注意,剩下的这些整数为(相邻彼此至少有一个空格隔开):“123”、“34”、“8” 和 “34” 。
返回对 word 完成替换后形成的 不同 整数的数目。
只有当两个整数的 不含前导零 的十进制表示不同, 才认为这两个整数也不同。
示例 1:

输入:word = “a123bc34d8ef34”
输出:3
解释:不同的整数有 “123”、“34” 和 “8” 。注意,“34” 只计数一次。

输入:word = “a1b01c001”
输出:1
解释:“1”、“01” 和 “001” 视为同一个整数的十进制表示,因为在比较十进制值时会忽略前导零的存在。

class Solution {
public:
    int numDifferentIntegers(string word) {
        set<string>s;//用set可进行去重
        string temp="";
        word+='a';//在字符串末尾加上一个字母,保证在遍历的时候如果有整数就不会遗漏
        for(char ch:word)
        {
            if(isalpha(ch))//如果是字母
            {
                if(!temp.empty())//临时字符串为空
                {
                    s.insert(temp);
                    temp.clear();
                }
            }
            else
            {
                if(temp=="0")temp.clear();//整数前面有0:如012就是12,将0清除
                temp+=ch;
            }
        }
        return s.size();
    }
};

最常见的单词
**题目描述:**给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。
题目保证至少有一个词不在禁用列表中,而且答案唯一。
禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。答案都是小写字母。
示例:
输入:
paragraph = “Bob hit a ball, the hit BALL flew far after it was hit.”
banned = [“hit”]
输出: “ball”
解释:
“hit” 出现了3次,但它是一个禁用的单词。
“ball” 出现了2次 (同时没有其他单词出现2次),所以它是段落里出现次数最多的,且不在禁用列表中的单词。
注意,所有这些单词在段落里不区分大小写,标点符号需要忽略(即使是紧挨着单词也忽略, 比如 “ball,”),
"hit"不是最终的答案,虽然它出现次数更多,但它在禁用单词列表中。

class Solution {
public:
    string mostCommonWord(string paragraph, vector<string>& banned) {
        paragraph+=" ";
        string temp="";
        map<string,int>m;//哈希表记录单词出现频次
        set<string>ban(banned.begin(),banned.end());//把禁用列表放到集合中方便查找
        for(char ch:paragraph)
        {
            if(!isalpha(ch))//将字符串中所有的单词分割出来
            {
                if(!temp.empty())
                {
                    m[temp]++;
                    temp.clear();
                }
            }
            else
            {
                temp+=tolower(ch);//将所有字母转换为小写字母
            }
        }
        vector<string>words;
        for(auto p:m)
        {
            words.push_back(p.first);
        }
         sort(words.begin(), words.end(), [&](string &s, string &p) { return m[s] > m[p]; }); 

        if(banned.empty())//如果没有禁用单词,直接返回排序后列表的首元素
        {
            return words[0];
        }
        for(auto w:words)//遍历列表,除了禁用单词外,第一个单词就是常见单词
        {
            if(ban.find(w)==ban.end())
            {
                return w;
            }
        }
        return "";

    }
};

山羊拉丁文
给定一个由空格分割单词的句子 S。每个单词只包含大写或小写字母。
我们要将句子转换为 “Goat Latin”(一种类似于 猪拉丁文 - Pig Latin 的虚构语言)。
山羊拉丁文的规则如下:
如果单词以元音开头(a, e, i, o, u),在单词后添加"ma"。
例如,单词"apple"变为"applema"。
如果单词以辅音字母开头(即非元音字母),移除第一个字符并将它放到末尾,之后再添加"ma"。
例如,单词"goat"变为"oatgma"。
根据单词在句子中的索引,在单词最后添加与索引相同数量的字母’a’,索引从1开始。
例如,在第一个单词后添加"a",在第二个单词后添加"aa",以此类推。
返回将 S 转换为山羊拉丁文后的句子。
示例 1:
输入: “I speak Goat Latin”
输出: “Imaa peaksmaaa oatGmaaaa atinLmaaaaa”

class Solution {
public:
    string toGoatLatin(string sentence) {
        sentence+=" ";
        vector<string>res; 
        string temp="";
        string vowels="aeiouAEIOU";
        for(char ch:sentence)
        {
            if(ch==' ')
            {
                res.push_back(temp);
                temp.clear();
            }
            else
            {
                temp+=ch;
            }
        }
        sentence.clear();
        for(int i=0;i<res.size();++i)
        {
            //字符串中单词的首元素为元音字母
            if(vowels.find(res[i][0])!=-1)
            {
                sentence+=res[i];
            }
            else
            {
                //如果不是,那么就将单词的首元素字母增加在原单词中,然后将首字母删除
                string t=res[i]+res[i][0];
                t.erase(t.begin());
                sentence+=t;
            }
            sentence+="ma";
            sentence.insert(sentence.size(),i+1,'a');
            sentence+=' ';
        }
        sentence.pop_back();
        return sentence;

    }
};

检查单词是否为句子中其他单词的前缀
给你一个字符串 sentence 作为句子并指定检索词为 searchWord ,其中句子由若干用 单个空格 分隔的单词组成。请你检查检索词 searchWord 是否为句子 sentence 中任意单词的前缀。
如果 searchWord 是某一个单词的前缀,则返回句子 sentence 中该单词所对应的下标(下标从 1 开始)。如果 searchWord 是多个单词的前缀,则返回匹配的第一个单词的下标(最小下标)。如果 searchWord 不是任何单词的前缀,则返回 -1 。
字符串 s 的 前缀 是 s 的任何前导连续子字符串。
示例 1:
输入:sentence = “i love eating burger”, searchWord = “burg”
输出:4
解释:“burg” 是 “burger” 的前缀,而 “burger” 是句子中第 4 个单词。

class Solution {
public:
    int isPrefixOfWord(string sentence, string searchWord) {
        sentence+=" ";
        string temp="";
        vector<string>res;
        for(char ch:sentence)
        {
            if(ch==' ')
            {
                res.push_back(temp);
                temp.clear();
            }
            else
            {
                temp+=ch;
            }
        }
        for(int i=0;i<res.size();++i)
        {
            if(res[i].find(searchWord)==0) return i+1;
        }
        return -1;

    }
};

重新排列单词间的空格
给你一个字符串 text ,该字符串由若干被空格包围的单词组成。每个单词由一个或者多个小写英文字母组成,并且两个单词之间至少存在一个空格。题目测试用例保证 text 至少包含一个单词 。
请你重新排列空格,使每对相邻单词之间的空格数目都 相等 ,并尽可能 最大化 该数目。如果不能重新平均分配所有空格,请 将多余的空格放置在字符串末尾 ,这也意味着返回的字符串应当与原 text 字符串的长度相等。
返回 重新排列空格后的字符串 。
用模板一

class Solution {
public:
    string reorderSpaces(string text) {
        text+=" ";
        string temp="";
        vector<string>res;
        int cnt=-1;//因为代码最开始给字符串增加了一个空格
        for(char ch:text)
        {
            if(ch==' ')
            {
                cnt++;
                if(!temp.empty())
                {
                    res.push_back(temp);
                    temp.clear();
                }
            }
            else
            {
                temp+=ch;
            }
        }
        text.clear();
        int n=res.size();
        if(n==1)
        {
            text+=res[0];
            text.insert(text.size(),cnt,' ');
            return text;
        }
        int bank=cnt/(n-1);
        int remain=cnt-bank*(n-1);
        for(int i=0;i<n-1;++i)
        {
            text+=res[i];
            text.insert(text.size(),bank,' ');

        }
        text+=res.back();
        if(remain>0)text.insert(text.size(),remain,' ');
        return text;

    }
};

将句子排序

class Solution {
public:
    string sortSentence(string s) {
        s += " ";
    string temp = "";
    vector<string> res;
    for (char ch : s)
    {
        if (ch == ' ')
        {
            res.push_back(temp);
            temp.clear();
        }
        else
            temp += ch;
    }
    s.clear();
    sort(res.begin(),res.end(),[&](string&a,string&b){return a.back()<b.back();});
    for(auto&str:res)
    {
        str.pop_back();//将单词中的数字清除
        s+=str+' ';
    }
    s.pop_back();
    return s;



    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值