力扣_初级算法_字符串_5~8题
一个C++的小白,在记录他的成长之路,见笑了见笑了
第5题:字符串转换整数(atoi)
题目描述:
请你来实现一个 atoi
函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:
- 如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
- 假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
- 该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0 。
提示:
- 本题中的空白字符只包括空格字符
' '
。 - 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。
举例:
示例 1:
输入: "42" 输出: 42
示例 2:
输入: " -42" 输出: -42 解释: 第一个非空白字符为 '-', 它是一个负号。 我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
示例 3:
输入: "4193 with words" 输出: 4193 解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
示例 4:
输入: "words and 987" 输出: 0 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。 因此无法执行有效的转换。
示例 5:
输入: "-91283472332" 输出: -2147483648 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 因此返回 INT_MIN (−231) 。
应用背景(自己琢磨的):找出文档中的首次出现的,连续的数字(及其前面的符号)
实现代码:(C++)
class Solution {
public:
int myAtoi(string str) {
int i=0;
int temp=0;
int num=0;
int flag=0;
while( str[i]==' ' ) { i++; } //把前面的空格跳过
if( str[i]=='-' ) { flag=1; } //若全部空格跳过后,下一个是负号,做个标记
if( str[i]=='-'||str[i]=='+' ) { i++; } //跳过符号
if( i==str.size() ) return 0; //①新学到一个关于字符串的函数size()
while( i<str.size()&&isdigit(str[i]) ) //②新学到一个关于字符串的函数isdigit(),用于判断括号类的字符是否为数字
{
temp=str[i]-'0'; //char类型转int类型
if( num>INT_MAX/10||(num==INT_MAX/10&&temp>7) ) //新学到C++里的INT_MAX和INT_MIN以及逆思维(防止越界)
return flag?INT_MIN:INT_MAX;
num=num*10+temp;
i++;
}
return flag?num*(-1):num;
}
};
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
第6题:实现strStr()
描述:
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
举例:
示例 1:
输入: haystack = "hello", needle = "ll" 输出: 2
示例 2:
输入: haystack = "aaaaa", needle = "bba" 输出: -1
应用背景(自己琢磨的):类似于excel(表格)里的“查找”功能,输入关键词,在文中找出最先出现的位置
实现代码:(C)
int strStr(char * haystack, char * needle){ //采用双指针
int i=0,j=0,s,flag=0,idx=0; //idx作为最后返回的下标
s=strlen(needle); //strlen()用于计算字符串的有效长度。遇到'\0'(即扫描到空字符截止)
if( s==0 ) return 0;
while( i<strlen(haystack) )
{
if( (haystack[i]==needle[j])&&(flag==0) )
{
flag=1; //标记改变,使得在后面的循环中,这个if语句直接跳过(目的:避免idx改变)
idx=i;
i++;
j++;
continue;
}
if( (haystack[i]==needle[j])&&(flag==1) )
{
i++;
j++;
continue;
}
if( j==s ) break; //当有符合的情况出现时,跳出循环。s:needle字符串的有效长度。j:指向needle的一个坐标
i=i-j+1; //确保能从haystack每个字母作为“火车头”开始,与needle匹配一遍
//并且在当j为0是,第二功能是i自加1,使得i指向的坐标,在haystack字符串上移动
j=0; //这条语句关键,使得j指向的坐标,返回到needle的开头
flag=0; //重置标记
}
if( j==s )
return idx;
else
return -1;
}
-------------------------------------------------------------------------------------------------------------------------
第7题:外观数组
描述:(表示,我看很久,才看懂...)
给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。
注意:整数序列中的每一项将表示为一个字符串。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下:
1. 1 2. 11 3. 21 4. 1211 5. 111221
第一项是数字 1
描述前一项,这个数是 1
即 “一个 1 ”,记作 11
描述前一项,这个数是 11
即 “两个 1 ” ,记作 21
描述前一项,这个数是 21
即 “一个 2 一个 1 ” ,记作 1211
描述前一项,这个数是 1211
即 “一个 1 一个 2 两个 1 ” ,记作 111221
备注: 就是把11读成“2个1”,下一个就是“21”; 接着把“21”读成“1个2,1个1”...“1211”
举例:
输入: 1 输出: "1" 解释:这是一个基本样例。
示例 2:
输入: 4 输出: "1211" 解释:当 n = 3 时,序列是 "21",其中我们有 "2" 和 "1" 两组,"2" 可以读作 "12",也就是出现频次 = 1 而 值 = 2;类似 "1" 可以读作 "11"。所以答案是 "12" 和 "11" 组合在一起,也就是 "1211"。
应用背景(自己琢磨的):实际应用不大,但感觉和 斐波纳契[fěi bō nà qì]数列有相像之处。使用递归,提升我们的思维能力。
实现代码:(C++)
class Solution {
public:
string countAndSay(int n) {
if( n==1 ) return "1"; //注意,这里返回的是字符串string,要用双引号。并且!一般将这种语句放在开头
int i,count=1,length;
string ancestor=countAndSay(n-1),result=""; //这里使用递归,为什么要定义两个string类型的变量?我们可以把ancestor看成炒菜的锅,result是放菜的大桌子。ancestor的内部要不停地比较,且不能 改变。而result是不断改变的。
length=ancestor.length(); //③新学到length( )这个函数
for( i=0;i<length;i++ )
{
if( ancestor[i]==ancestor[i+1] ) //注:这里不会越界,因为string类型的最后都是以'\0'结尾的。
count++;
else
{
result+=to_string(count)+ancestor[i]; //④新学到to_string( )函数,用于将int类型/double等类型转换为string类型
count=1;
}
}
return result;
}
};
-------------------------------------------------------------------------------------------------------------------------
第8题:最长公共数组
描述:
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
举例:
示例 1:
输入: ["flower","flow","flight"] 输出: "fl"
示例 2:
输入: ["dog","racecar","car"] 输出: "" 解释: 输入不存在公共前缀。
应用背景(自己琢磨的):可用于匹配单词前驱相似度,看看是否是同根生。
实现代码:(C++)
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) { //⑤了解了vector是C++的标准库函数,类似于“stdio.h”。它是个“容器”,想进一步了解vector,建议去看B站的企业级开发经理的一节课 https://www.bilibili.com/video/BV1at41147p8
if( !strs.size() ) return "" ; //这个语句一定要放在开头,具体原因我还没摸索出来
int i=0;
string prefix=strs[i]; //prefix:前缀字符串
while( i<strs.size()-1&&prefix!="" ) //strs.size()这里减1,是为了在后面的函数体内避免越界
{
i++;
prefix=longest_common_prefix( prefix,strs[i] );
if( !prefix.size() ) break; //如果prefix已经是空串了,就不用进行后续循环了,直接跳出
}
return prefix;
}
string longest_common_prefix( string &str_1,string &str_2 ) //引用调用
{
int i=0,index,min_length;
min_length=min( str_1.size(),str_2.size() ); //⑥新学到字符串函数 min( 整数, 整数 )
while( i<min_length&&str_1[i]==str_2[i] ){
i++;
}
str_1=str_1.substr(0,i); //⑦新学到字符串函数substr( 继承的坐标首位, 需要继承的位数 ) ,例:i为5,则继承5个数字
return str_1;
}
};
posted on 2020-07-08 22:22 Wangdoudou8 阅读(78) 评论(0) 编辑 收藏 举报