C++的string类(二):string类的实际OJ应用

目录

1、找出字符串中第一个只出现一次的字符

2、字符串相乘

3、反转字符串中的单词 III

4、反转字符串 II

5、字符串相加

6、验证回文串

7、字符串最后一个单词的长度

8、字符串中的第一个唯一字符

9、仅仅反转字母


1、找出字符串中第一个只出现一次的字符

#include <string>
#include <iostream>
using namespace std;int main()
{string words;while(cin >> words){bool IsFound = false;for(int i =0;i<words.size();i++){if(words.find_first_of(words[i]) == words.find_last_of(words[i])){cout << words.at(i) << endl;IsFound = true;break;}}if(!IsFound) cout << "-1" << endl;}return 0;
}
  • find_first_of从前向后找所给字符的位置(作用之一)
  • find_last_of:从后向前找所给字符的位置(作用之一)
  • 题解:同时从前和后两个方向寻找同一个字符,找到位置相等则该元素只出现一次,否则该元素在字符串中出现两次

2、字符串相乘

解法一:

#include <string>
class Solution {
public:            //num1是乘数,num2是被乘数string multiply(string num1, string num2) {if(num1 == "0" || num2 == "0")//一个为0相乘结果为0return "0";string ans = "0";//初始化存放最终结果的对象int m = num1.size() - 1,n = num2.size() - 1;//m和n分别表示乘数和被乘数的下标for(int i = n ;i >= 0;i--)//从右向左循环遍历被乘数的每一位{   string curr;//curr作为每次的结果int add = 0;//add存储相乘时进位产生的数值for(int j = n;j > i ;j--)//在开始相乘前补零{curr.push_back(0);}int y = num2[i] - '0';//获取被乘数下标为i的字符的对应整数for(int j = m ;j >= 0;j--)//乘数每一位*被乘数{int x = num1[j] - '0';//获取乘数下标为j的字符的对应整数int product = x * y + add;//乘数的个/十/百...位 * 个/十/百...位 + 进位的数值curr.push_back(product % 10);//取出每次计算的最小位尾插进curradd = product / 10;//获取进位数值}while(add != 0)//for结束时add可能还有(1234*9,最后add = 10,还可以再尾插一个1){curr.push_back(add % 10);add /= 10;//将该加的都加上}reverse(curr.begin(),curr.end());//翻转字符串(8368->8638,string只有尾插没头插)for (auto &c : curr)//将ans每个字符转变为对应的整数?{c += '0';}ans = addstring(ans,curr);//每轮相乘的结果传递给add函数进行结果叠加,ans是字符串}return ans;//循环结束后返回最终答案}//("0","8638")string addstring(string& n1,string& n2){   //(i = 0,j = 3,add = 0,)int i = n1.size() - 1, j = n2.size() - 1, add = 0;//i和j是两个下标,add还是进位数值string ans;//每次相加的结果while(i>=0 || j>=0 || add!=0)//让能加的全加完故不用&&,两个数的每一位从右至左一次相加{int x = i >= 0 ? n1[i] - '0' : 0;//下标小于0,则没有什么可以加的了,将其赋值为0即可int y = j >= 0 ? n2[j] - '0' : 0;//下标大于等于0,则获取下标对应的数值int result = x + y + add;//每位相加的同时将之前进位的数值也加上ans.push_back(result % 10);//取结果的最小位尾插进ans,该位会被视为字符插入add = result / 10;//获取进位数值i--;//向前比较j--;}reverse(ans.begin(),ans.end());//翻转字符串for (auto &c : ans)//隐式转换,看下面的题解{c += '0';}return ans;}
};

题解: 

  • i初始值为n,每轮i--,但每轮j=n,且j>i,故每轮j循环多一次,被乘数的个/十百位逐渐变为0
  • reverse是翻转字符串,reserve是开辟空间,前者要<algorithm>,后者要<string>
  • push_back(2)在ans中存放的是ASCII码值为2的特殊字符而不是ASCII码值为50的'2',2 +'48' = 2 + 48 = 50 = '2' 

解法二: 

class Solution {
public://num1乘数,num2是被乘数string multiply(string num1, string num2) {if (num1 == "0" || num2 == "0") {return "0";}int m = num1.size(), n = num2.size();//m和n分别表示num1和num2的大小auto ansArr = vector<int>(m + n);//num1和num2相乘最大的空间是m+nfor (int i = m - 1; i >= 0; i--)//i和j分别表示乘数和被乘数的下标,从右至左逐位遍历{int x = num1[i] - '0';//字符转整数for (int j = n - 1; j >= 0; j--) {int y = num2[j] - '0';ansArr[i + j + 1] += x * y;//叠加}}for (int i = m + n - 1; i > 0; i--)//提取进位{ansArr[i - 1] += ansArr[i] / 10;//将当前坐标中的数的十位进位加到下一个坐标的存储的数值中ansArr[i] %= 10;//当前坐标存储只存储个位数}int index = ansArr[0] == 0 ? 1 : 0;//最高位是否为0,如果是则拷贝的下标从1开始,如果不是则从0开始string ans;//返回结果while (index < m + n) {ans.push_back(ansArr[index]);//向ans中尾插index++;}for (auto &c: ans)//方法一同理{c += '0';}return ans;}
};

3、反转字符串中的单词 III

解法一: 

class Solution {
public:string reverseWords(string s) {string ret;int size = s.size();int i = 0;while (i < size) {int start = i;//子串的首下标start// 寻找第一个空格while (i < size && s[i] != ' '){i++;}//i的下标是空格的下标而不是空格前一个字符的下标// 将找到的单词逆序加入结果字符串for (int pos = i - 1; pos >= start; --pos)//空格前一个字符的下标是子串的尾下标pos{ret.push_back(s[pos]);}//在子串间插入空格,最后一个子串不进行尾插if(i < size){ret.push_back(' ');}i++; // 跳过当前的空格字符}return ret;}
};

解法二:


class Solution {
public:string reverseWords(string s) {int start = 0;for(int i = 0;i<s.size();i++)//i用来遍历整个数组下标{if(s[i+1]==' ' || i+1 == s.size())//即将到达空格或者边界{reverse(s.begin() + start,s.begin() + i + 1);//reverse的翻转范围是左闭右开的,空格刚好不会被翻转start = i + 2;//令start跳过空格}}return s;}
};

4、反转字符串 II

class Solution {
public:string reverseStr(string s, int k) {for (int i = 0; i < s.size(); i += (2 * k))//每2*k个字符为一段待翻转字符{if (i + k <= s.size())//i+k只要不小于size就证明还能再翻转k个,就将k个字符进行翻转{reverse(s.begin() + i, s.begin() + i + k);continue;}//不能翻转k个就将剩余的全部翻转reverse(s.begin() + i, s.begin() + s.size());//翻转[i,size)范围内的字符}return s;}
};
  • 题目很唬人,但是将条件整合即可 

5、字符串相加

class Solution {
public:string addStrings(string num1, string num2) {string ans = "";int i = num1.size() - 1,j = num2.size() - 1,add = 0;//i和j分别表示num1和num2的下标,add存放进位值while(i >= 0 || j >= 0 || add != 0){   int x = i >= 0 ? num1[i] - '0' : 0;int y = j >= 0 ? num2[j] - '0' : 0;int result = x + y + add;ans.push_back(result % 10 + '0');//直接在插入时解决之前要用for来解决的+='0'问题add = result / 10;//简简单单--i;--j;}reverse(ans.begin(),ans.end());return ans;}
};
  • 跟字符串相乘处对字符的加操作一致,同时将最后for处理的内容直接在push_back处理了 

6、验证回文串

解法一: 

class Solution {
public:bool isPalindrome(string s) {string sgood;for (auto ch: s)//逐个读取字符串字符{if (isalnum(ch))//判断是否是字母或数字,是就插入sgood,不是就跳过,这样就不用管空格了{sgood += tolower(ch);}}string sgood_rev(sgood.rbegin(), sgood.rend());//翻转sgood的时将翻转结果存入sgood_revreturn sgood == sgood_rev;//返回判断新旧字符串是否相等的结果}
};
  • isalnum()函数用于检查一个字符是否是字母或数字
  • tolower()函数检查
  • 对string类类型字符串的+=说函数重载后的结果,表示尾插
  • 利用范围for和auto关键字可以很好的遍历string类类型的字符串

解法二:

class Solution {
public:bool isPalindrome(string s) {string sgood;for (char ch: s) {if (isalnum(ch)) {sgood += tolower(ch);}}int n = sgood.size();int left = 0, right = n - 1;while (left < right) {if (sgood[left] != sgood[right]) {return false;}++left;--right;}return true;}
};
  • 双指针?easy,拿下

解法三:

class Solution {
public:bool isPalindrome(string s) {//回文串左右两端的字母应该是对称的int n = s.size();int left = 0, right = n - 1;while (left < right) {while (left < right && !isalnum(s[left]))//跳过非数字和字母,如果s[left]处是数字和字母则!isalnum结果为假,否则为真{//当返回结果为真(s[left]处不是字母和数字就令left向右走到一个s[left]处是字母和数字的位置)++left;}//防止比较过程中出现的空字符打乱比较对象,只能让字母和数字参与比较while (left < right && !isalnum(s[right]))//同理{--right;}if (left < right)//如果此时两指针仍未相遇{if (tolower(s[left]) != tolower(s[right]))//判断双方此时所指向的字母(已转换为小写)是否相同{return false;//只要有一个不同就返回false}++left;//如果相同就令两指针继续向中间靠拢--right;}}return true;/循环结束则返回true}
};
  • 遇到空格就继续向前走,因为空格不是参与比较的对象 

7、字符串最后一个单词的长度

抽象题解: 

#include<iostream>
using namespace std;int main() {string s;while(cin >> s);cout << s.size();return 0;
}

C++题解:

#include <iostream>
#include<string>
#include <algorithm>
using namespace std;int main()
{string a;getline(cin, a);int size = a.size(),count = 0;reverse(a.begin(),a.end());while(a[count]!=' ' && count < size)//注意考虑整个字符串就是一个单词的情况{count++;}cout<<count;
}
  •  getline() 函数是用于从输入流中读取一行文本的函数

8、字符串中的第一个唯一字符

class Solution {
public:int firstUniqChar(string s) {for(int i = 0; i < s.size() ; i++){if(s.find(s[i]) == s.rfind(s[i])){return i;}}return -1;}
};
  • find从左向右找子串第一次出现的位置,rfind从右向左找子串第一次出现的位置
  • find_first_of正向查找在原字符串中第一个与指定字符串(或字符)中的某个字符匹配的字符,返回它的位置
  • find_last_of逆向查找在原字符串中最后一个与指定字符串(或字符)中的某个字符匹配的字符,返回它的位置,逆向查找因为有'\0'所以最后一个有效字符的索引为1,'\0'为0

  • string str=“abcdefab”;
  • cout<<str.find_last_of(“wab”,5)<<endl;//从原串中下标为5开始逆向查找,首先f与待查子串每一字符比较,若有相同的就输出该字符在原串的下标。若一个都没有,就依次逆向比较,即e再与待查子串一一比较,直到原串的b与待查子串中的b相同,然后输出该b在原串的下标1

9、仅仅反转字母

解法一: 

class Solution {
public:string reverseOnlyLetters(string s) {int n = s.size();int left = 0, right = n - 1;while (true) {while (left < right && !isalpha(s[left])) { // 判断左边是否扫描到字母left++;}while (right > left && !isalpha(s[right])) { // 判断右边是否扫描到字母right--;}if (left >= right)//双指针相遇或相遇后错开就终止循环{break;}swap(s[left], s[right]);//交换此时两个指针所指向的字母left++;right--;}return s;}
};
  • isalpha()C++标准库函数,用于检查字符是否为字母字符,包含在<cctype>头文件 

解法二:

class Solution {
public:string reverseOnlyLetters(string S) {int begin = 0,end=S.length()-1;while(begin<end){if(!isalpha(S[begin]))begin++;if(!isalpha(S[end])) end--;if(isalpha(S[begin])&&isalpha(S[end]))swap(S[begin++],S[end--]);}return S; }
};

~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/773096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nacos服务分级存储(权重配置)

需求&#xff1a;服务器分级存储的访问优先级&#xff1f; 一个服务可以有多个实例&#xff0c;例如我们的user-service&#xff0c;可以有: 127.0.0.1:8081 127.0.0.1:8082 127.0.0.1:8083 这里user服务copy了三个实例出来、。 127.0.0.1:8083杭州127.0.0.1:8082成都127.…

Python包管理工具 pip 及其常用命令和参数用法

目录 PIP 主要功能 安装包 升级包 卸载包 列出包 检查依赖 pip的配置和环境 主要用法 1&#xff1a;版本 2&#xff1a;安装 Python 库 3&#xff1a;升级库 4&#xff1a;卸载库 5&#xff1a;搜索库 6&#xff1a;查看已安装库详细信息 7&#xff1a;只下载库…

POE供电IP网络广播号角 网络号角喇叭SV-7044

POE供电IP网络广播号角 网络号角喇叭SV-7044 SV-7044是一款网络号角喇叭&#xff0c;具有10/100M以太网接口&#xff0c;从网络接口接收网络的音频数据后播放。 本网络号角喇叭内置有一个高品质扬声器&#xff0c;提供立体声的音频播放。该网络号角喇叭可以直接播放来自网络的音…

00000基础搭建vue+flask前后端分离项目

我完全是参考的这个vue3flask前后端分离环境速建_flask vue3-CSDN博客 安装了node_js&#xff08;添加了环境变量&#xff09; 环境变量 把原来的镜像源换成了淘宝镜像源 npm config set registry https://registry.npmmirror.com/ 查看版本证明安装成功 npm - v 安装npm i…

学习Dive into Deep learning:2.1数据操作,张量(tensor)

首先&#xff0c;我们介绍n维数组&#xff0c;也称为张量&#xff08;tensor&#xff09;。 使用过Python中NumPy计算包的读者会对本部分很熟悉。 无论使用哪个深度学习框架&#xff0c;它的张量类&#xff08;在MXNet中为ndarray&#xff0c; 在PyTorch和TensorFlow中为Tensor…

(二)Eureka服务搭建,服务注册,服务发现

1.Eureka注册中心 假如我们的服务提供者user-service部署了多个实例&#xff0c;如图&#xff1a; 存在几个问题&#xff1a; order-service在发起远程调用的时候&#xff0c;该如何得知user-service实例的ip地址和端口&#xff1f;有多个user-service实例地址&#xff0c;…

HCIP—BGP路由发布

R1和R2&#xff0c;R4和R5建立EBGP对等体 R1和R2&#xff08;R4和R5&#xff09;之间属于EBGP对等体&#xff0c;可以使用直连物理接口建立对等体关系&#xff0c;TTL值默认1。由于使用直连物理接口方式建立&#xff0c;刚好一跳到达。 [R1]bgp 100 [R1-bgp]router-i…

【Frida】【Android】02_JAVA层HOOK

&#x1f6eb; 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

Trapcode Particular---打造惊艳粒子效果

Trapcode Particular是Adobe After Effects中的一款强大3D粒子系统插件&#xff0c;其能够创造出丰富多样的自然特效&#xff0c;如烟雾、火焰和闪光&#xff0c;以及有机的和高科技风格的图形效果。Trapcode Particular功能丰富且特色鲜明&#xff0c;是一款为Adobe After Eff…

用 JavaScript 发起 HTTP 请求的几种方法

JavaScript 具有非常棒的模块和方法&#xff0c;可以用来建立可从服务器端资源发送或接收数据的 HTTP 请求。本文会带着大家一起看看在 JavaScript 中常用的建立 HTTP 请求的方式有哪些。 Ajax Ajax 是最常规的建立异步 HTTP 请求的方式。你可以使用 HTTP POST 方法来发送数据…

第44期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

MT6762_联发科MTK6762安卓核心板规格参数

MTK6762核心板是一款集成了蓝牙、fm、wlan和gps模块的高度集成基带平台&#xff0c;为LTE/LTE-A和C2K智能手机应用程序提供支持。该安卓核心板集成了ARM Cortex-A53处理器&#xff0c;工作频率可达2.0GHz&#xff0c;并且还集成了功能强大的多标准视频编解码器。除此之外&#…

汽车电子行业知识:智能汽车电子架构

文章目录 3.智能汽车电子架构3.1.汽车电子概念及发展3.2.汽车电子架构类型3.2.1.博世汽车电子架构3.2.2.联合电子未来汽车电子架构3.2.3.安波福汽车电子架构3.2.4.丰田汽车电子架构3.2.5.华为汽车电子架构 3.智能汽车电子架构 3.1.汽车电子概念及发展 汽车电子是车体汽车电子…

负氧离子监测站:创造健康生活环境

TH-FZ5在蓝天白云之下&#xff0c;那一座座高耸的全彩屏负氧离子监测站&#xff0c;如同一支支科技的绿芽&#xff0c;静静破土而出&#xff0c;为这片土地带来了新的生命力。这些现代化的设备不仅美化了环境&#xff0c;更是我们呼吸健康守护者&#xff0c;它们的存在让我们的…

【排序算法】深入解析快速排序(霍尔法三指针法挖坑法优化随机选key中位数法小区间法非递归版本)

文章目录 &#x1f4dd;快速排序&#x1f320;霍尔法&#x1f309;三指针法&#x1f320;挖坑法✏️优化快速排序 &#x1f320;随机选key&#x1f309;三位数取中 &#x1f320;小区间选择走插入&#xff0c;可以减少90%左右的递归&#x1f309; 快速排序改非递归版本&#x1…

【笔记】OpenHarmony设备开发:搭建开发环境(Ubuntu 20.04,VirtualBox 7.0.14)

参考&#xff1a;搭建开发环境&#xff08;HarmonyOS Device&#xff09; Note&#xff1a;Windows系统虚拟机中Ubuntu系统安装完成后&#xff0c;根据指导完成Ubuntu20.04基础环境配置&#xff08;HarmonyOS Connect 开发工具系列课&#xff09; 系统要求 Windows系统要求&…

OC 技术 苹果内购

一直觉得自己写的不是技术&#xff0c;而是情怀&#xff0c;一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的&#xff0c;希望我的这条路能让你们少走弯路&#xff0c;希望我能帮你们抹去知识的蒙尘&#xff0c;希望我能帮你们理清知识的脉络&#xff0…

Linux文件和文件夹操作

一、文件操作 功能项命令实例作用文件创建vi /opt/learn/hello.txt 在目录/opt/learn下创建文件hello.txt并进入vi编辑界面 touch /opt/learn/test在目录/opt/learn下创建空白文件testcat > /opt/catfile创建文件catfile并在屏幕上输入内容&#xff0c;最后按 Ctrl D 退出…

【学习心得】神经网络知识中的符号解释

这里我对我学到的神经网络知识中&#xff0c;常见的符号做一下记录和总结&#xff0c;方便自己在后面学习中复习。下图二分类识别图像识别猫为例。为了保存一张图片&#xff0c;需要三个矩阵&#xff0c;它们分别对应图片中的红、绿、蓝三种颜色通道&#xff0c;如果图片大小为…

Django路由

Router介绍 在实际开发过程中&#xff0c;一个Django项目会包含很多的app,这时候如果我们只在主路由里进行配置就会显得杂乱无章&#xff0c;所以通常会在每个app里&#xff0c;创建各自的urls.py路由模块&#xff0c;然后从根路由出发&#xff0c;将app所属的url请求&#xff…