字符串
本博客的题均为leetcode上的摘录,都是我的刷题答案,仅做参考,若有错误,欢迎指正
字符串实际上是一个 unicode 字符
数组。你可以执行几乎所有我们在数组中使用的操作。
在C++里面还支持可变长度的字符串,可以使用String和vector等标准模版进行操作。
一、二进制求和
给定两个二进制字符串,返回他们的和(用二进制表示)。
输入为非空字符串且只包含数字 1
和 0
。
示例 1:
输入: a = "11", b = "1" 输出: "100"
示例 2:
输入: a = "1010", b = "1011" 输出: "10101"
//C++实现
class Solution {
public:
string addBinary(string a, string b) {
int size_a=a.size()-1; //获取a字符串的长度
int size_b=b.size()-1; //获取b字符串的长度
if(a.empty() && b.empty()) //单独处理字符串为空的情况
return "";
else if(a.empty())
return b;
else if(b.empty())
return a;
string ret;
int flag=0;
for(;size_a >= 0 || size_b >= 0;size_a--,size_b--)
{
int a_bit; //存储a和b字符串的数字0或1
int b_bit;
if(size_a<0) //如果长度为0,当作0处理
a_bit=0;
else //将a字符串的字符‘1’或‘0’转换为数字的1或0
{
if(a[size_a]=='0')
a_bit=0;
else if(a[size_a]=='1')
a_bit=1;
}
if(size_b<0) //如果长度为0,当作0处理
b_bit=0;
else //将b字符串的字符‘1’或‘0’转换为数字的1或0
{
if(b[size_b]=='0')
b_bit=0;
else if(b[size_b]=='1')
b_bit=1;
}
//将a,b和进位标志的值相加,确定当前位的值以及进位标志的值
switch(a_bit+b_bit+flag)
{
case 0: //三者相加为0,当前位为0,不进位
ret+='0';
flag=0;
break;
case 1: //三者相加为1,当前位为1,不进位
ret+='1';
flag=0;
break;
case 2: //三者相加为2,当前位为0,进位
ret+='0';
flag=1;
break;
case 3: //三者相加为3,当前位为1,进位
ret+='1';
flag=1;
break;
}
if(max(size_a,size_b)==0) //当a和b两个的长度中较大的值减到0(到了最高位)
{
if(flag==1) //在判断进位标志是否进位,如果进位还需要加一位1
ret+='1';
}
}
reverse(ret.begin(),ret.end()); //要对二进制加法之后的字符串进行反转输出
return ret;
}
};
二、实现 strStr()
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll" 输出: 2
示例 2:
输入: haystack = "aaaaa", needle = "bba" 输出: -1
说明:
当 needle
是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle
是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
//C++实现
class Solution {
public:
int strStr(string haystack, string needle) {
int size_hay=haystack.size(); //获取两个字符串的长度
int size_nee=needle.size();
if(size_nee>size_hay) //needle长度不能大于haystack的长度
return -1;
if(haystack.empty() && needle.empty()) //如果两个都为空,返回0
return 0;
int i=0;
int j=0;
while(i<size_hay && j<size_nee)
{
if(haystack[i]==needle[j]) //有一个字符匹配成功
{
i++; //两个字符串同时向后移位一位,再进行匹配
j++;
}
else //如果匹配不成功,needle的索引回到起点[即0位]
{
i=i-j+1; //haystack索引回到i-j+1
j=0;
}
}
if(j==size_nee) //j加到needle的长度,即匹配成功
return i-j;
return -1;
}
};
这个题目的代码其实是一个经典的匹配算法:KMP算法,有兴趣的朋友可以去了解一下,但是我这里的解决办法并不是使用KMP算法进行处理的,只是根据我个人的理解想出来的处理算法,仅做参考。
这里比较难理解的,还是当字符匹配不成功的时候,haystack的索引 i 为什么退回 i-j+1,i-j其实是字符串needle的第一个字符匹配到haystack的第i-j个字符,当needle字符串匹配到第j个字符时匹配失败,就需要从haystack的第 i-j 后的那一位重新开始匹配,即 i-j+1 位重新开始匹配。
三、最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
示例 1:
输入: ["flower","flow","flight"] 输出: "fl"
示例 2:
输入: ["dog","racecar","car"] 输出: "" 解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z
。
//C++实现
#include<algorithm>
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
int size=strs.size();
vector<int> len;
string ret;
if(strs.empty()) //排除字符串空的情况
return "";
//获取vector里面每个字符串的长度
for(int i=0;i<size;i++)
{
len.push_back(strs[i].size());
}
int size_min=*min_element(len.begin(),len.end()); //获取字符串数组里面的字符串的最短长度
//*min_element(v.begin(),v.end())返回的是最小值【同样适用于数组,输入数组的地址即可】
//max_element(v.begin(),v.end()) - v.begin()返回的是最小值的索引
for(int i=0;i<size_min;i++)
{
int flag=0; //flag记录是否全都相等
//遍历vector的所有字符串,比较是否在相同的位有相同的字符
for(int j=0;j<size;j++)
{
if(strs[j][i]!=strs[0][i]) //一旦有一个字符串的对应位不相等,flag置1
flag=1;
}
if(flag==1) //如果flag为1,即该位不再是相同的字符,退出循环,返回共同的字符串
break;
else
ret+=strs[0][i]; //如果所有的字符串对应的位都相同,ret加上相同的字符
}
return ret; //返回相同的字符
}
};