C++算法(二)

发布时间:2026/10/4 7:44:02
C++算法(二) ༺ 个人主页 · 纪念229 ༻我的博客主页༒专栏目录《数据结构》༒༒专栏目录《算法》༒༒专栏目录《C》༒༒专栏目录《MySQL数据库》༒༒专栏目录《前端开发》༒༒其它有趣的计算机知识༒༺世上本没有路走的人多了自然就有了༻本文讲述的是string类的OJ题希望对你有所帮助后面可能还会讲一些有关C内存分布的题题目链接找字符串中第一个只出现一次的字符验证一个字符串是否是回文翻转字符串文章目录1.找字符串中第一个只出现一次的字符2.验证一个字符串是否是回文3.翻转字符串4.C内存分布题目讲解1.找字符串中第一个只出现一次的字符题目是核心代码模式我们看到题目里测试的字符串全是小写字符我们可以创建一个26个元素的整型数组来计出现的小写字符我们知道查到的小写字符a~z减a在下标0-25之间个数遍历字符数组给计数数组计数最后利用数组和s得到第一个计数为一的唯一字符并利用下标返回该下标(遍历字符数组利用计数数组返回第一个唯一字符)class Solution{public:intfirstUniqChar(string s){//因为题目通常只包括小写字母可以为大小为26的数组代替哈希表//通过小写字母26个字符形成数组将字符串中字符个数记好//然后遍历这个26数组将第一个数据为1的下标返回intcount[26]{0};//第一次遍历统计每个字符出现的个数//统计每个字符出现的个数可以用范围forfor(chare:s){count[e-a];}//第二次遍历返回count数组中数据为1的s上的下标(通过遍历s数组利用count数组)//用s[i] - a就可以得到count数组的下标//用范围for返回不了下标for(inti0;is.length();i)// 中间要写范围for(int i 0; s.length(); i){//这里是通过数组count计数小写字母最后遍历数组s将其减a来判断count数组里是否有为1的数据如果有就将当时遍历在s上的下标返回如果没有就返回-1if(count[s[i]-a]1)returni;}//如果count中没有为1的数据就返回-1return-1;}};int count[26] {0};创建一个计数数组for(chare:s){count[e-a];}这里遍历字符数组string因为用不上下标用范围for遍历方便将遍历的字符与’a’相减得到下标0~25之间的下标进行计数加加for(inti0;is.length();i)// 中间要写范围for(int i 0; s.length(); i){//这里是通过数组count计数小写字母最后遍历数组s将其减a来判断count数组里是否有为1的数据如果有就将当时遍历在s上的下标返回如果没有就返回-1if(count[s[i]-a]1)returni;}遍历字符数组用for循环遍历得到第一个唯一字符if(count[s[i] - a] 1)这里也是将s数组中的字符减’a’得到下标指向的数据是否为1为一就返回字符数组此时遍历的下标return -1;如果计数数组没有为一的数据就返回-1表示没找到题目示例中有2.验证一个字符串是否是回文这里就是注意两点1.仔细看题我看成是将大写字符转换为小写将小写字符和数字字符我没记数字字符放入另一个数组中然后判断回文注意小写字符和数字字符之间的关系是||不能是没有既是字母字符又是数字字符的字符2.大写字符加32就是它的小写字符我写成了大写字符减去32是它的小写字符错误题目是核心代码模式boolispr(string s){for(inti0;is.size();i){if(s[i]As[i]Z)// if(s[i] A s[i] Z) 字符要加否则会当成名字{s[i]32;// s[i] - 32;大写字母加32才是小写字母}}string s1s;inti0;for(intj0;js.size();j){if(s[j]as[j]z||s[j]0s[j]9)// if(s[j] a s[j] z s[j] 0 s[j] 9)这里字符不可能既是字母字符又是数字字符所以要用||// if(s[j] a s[j] z )这里除了管字符还有数字{s1[i]s[j];i;//这个i不仅是下标它还作为s1的有效字母个数进行判断回文}}//i等于1或0都是回文直接返回true;intleft0,righti-1;while(leftright){if(s1[left]!s1[right]){returnfalse;}left;right--;// right;这里right是--不是}returntrue;}class Solution{public:boolisPalindrome(string s){returnispr(s);}};for(inti0;is.size();i){if(s[i]As[i]Z)// if(s[i] A s[i] Z) 字符要加否则会当成名字{s[i]32;// s[i] - 32;大写字母加32才是小写字母}}这里也可以用范围for首先将字符数组中的大写字符(e ‘A’ e ‘Z’ )加32变成小写字符string s1s;inti0;for(intj0;js.size();j){if(s[j]as[j]z||s[j]0s[j]9)// if(s[j] a s[j] z s[j] 0 s[j] 9)这里字符不可能既是字母字符又是数字字符所以要用||// if(s[j] a s[j] z )这里除了管字符还有数字{s1[i]s[j];i;//这个i不仅是下标它还作为s1的有效字母个数进行判断回文}}先使用拷贝构造拷贝一个字符数组在定义一个int类型的i为0遍历赋值最后作为有效数据进行进行回文判断注意这里要放的是字母字符和数字字符(s[j] ‘a’ s[j] ‘z’ || s[j] ‘0’ s[j] ‘9’ )字母字符与数字字符之间是||不是intleft0,righti-1;while(leftright){if(s1[left]!s1[right]){returnfalse;}left;right--;// right;这里right是--不是}returntrue;放完字符串进行判断是否回文(不用考虑有效数据i的个数为0和1的情况这些字符串都是回文)将排好的字符串左右两边比较如果不相等就返回false如果都相等就循环结束返回true3.翻转字符串有个函数可以直接将字符串翻转)reverse(初始迭代器末迭代器)算法头文件里#inclide里的函数reverse可直接实现反转字符它不是vector、string里的成员函数它还可以反转多种类型的数组char、int…vector是类模板题目是核心代码模式class Solution{public:voidreverseString(vectorchars){reverse(s.begin(),s.end());}};直接调用此reverse即可有些知识点没提是因为之前文章有讲这里就不赘述了4.C内存分布题目讲解C 这里是编译时检查数据类型B 这里是函数模板 B中的实参类型不同不符合函数模板的调用A 、C实参类型相同 D将实参隐式类型转换为float这里都是隐式实例化调用模板函数显示实例化就在目标前加一个template调用模板类显示实例化就在目标前加一个template classtemplateclass/typename T(这是模板)这里模板类是 template class Stack d(调用)类模板是template class/typename T(定义)写一个类D 类模板里的成员函数都是函数模板类模板里的成员函数调用在类外定义结构template返回类型 类名:: 函数名(形参…){…}就是在目标上面加个模板在函数名前加类名类型名::文章到此就告一段落希望对你有所帮助感谢观看