第一,在遍历数组时或容器时
尤其是在for()循环的语句块中要改变 i 的值时,一定要注意在for()循环的三个语句中是否有必要写变量自增与自减的语句。
class Solution {
public:
int lengthOfLastWord(string s) {
int ans=0;
for(int i=s.size()-1;i>=0; ){//此处空着,在循环体内写变量变化的语句
if(s[i]==' '){
i--;
}
else{
while(i>=0&&s[i]!=' '){
ans++;
i--;
}
break;
}
}
return ans;
}
};
2021/1/21补充
今天在做力扣1422. Maximum Score After Splitting a String时,在倒着遍历给定的串s,给数组cnt1中的元素进行赋值时,出现了内存溢出错误。
class Solution {
public:
int maxScore(string s) {
int cnt0[5100]={0},cnt1[5100]={0};
int now=0;
for(int i=0;i<s.size();i++){
if(s[i]=='0') now++;
cnt0[i]=now;
}
now=0;
for(int i=s.size()-1;i>0;i++){//出错点
if(s[i]=='1') now++;
cnt1[i]=now;
}
int ans=-1;
for(int i=0;i<s.size()-1;i++){
ans=max(ans,cnt0[i]+cnt1[i+1]);
}
return ans;
}
};
放到本地IDE进行调试时,发现,在第二个for循环中,本来是倒着遍历数组,结果是变量进行了++操作。这是一个非常容易就犯的错误。
第二,所给数据是否有前导0
在有的算法题中,会在有些测试点的数据里面放置前导0,例如(后序添加题目链接),这种情况之下,需要首先将前导0去掉。
第三,关于容器的容量
今天在写n皇后问题时n皇后问题,遇到一个问题,问题涉及到,vector容器的size()函数
如下所示
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> ans;
cout<<ans.size()-1;
return 0;
}
运行结果为
定义了一个vector容器ans,并且未在里面放东西,所以ans.size()为0是正确的,但是当输出ans.size()-1时,确并未输出-1,这是因为容器的size()返回的是无符号整数,平时用来遍历还是可以的,不涉及进行加减操作,但是当用来加减操作时,要注意无符号整型与有符号整型的运算,可能结果和想象的不同,最好不要使用size()的结果值运算,如果非要运算,可以定义一个int类型的数,先将size()的值保存下来。可以避免想不到的错误。
2021/1/21补充,做力扣1544. Make The String Great又遇到这种情况了,原来有错误的代码如下
class Solution {
public:
string makeGood(string s) {
for(int i=0;i<s.size()-1; ){//注意点
if(abs(s[i]-s[i+1])==32){
s.erase(i,2);
if(i) i--;
}
else i++;
}
return s;
}
};
运行代码时,显示堆栈溢出,可是有的样例可以通过,而样例"abBAcC"通不过,只好弄在本地IDE上,
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
int main()
{
string s="abBAcC";
for(int i=0;i<s.size()-1; ){
if(abs(s[i]-s[i+1])==32){
s.erase(i,2);
if(i) i--;
}
else i++;
cout<<i<<" "<<s.size()-1<<" "<<s<<endl;
}
cout<<s;
return 0;
}
为了方便观察变量,每一步都将当前的i与s输出,运行结果截图
后面还有好多,没有截出来,原来是,当s变成“cC”时还没错,但是接下来就出错了,因为下一步时,i变为0,串s变为“”,即空串,空串的长度为0,但是在for循环的判断语句中,使用了i与s.size()-1进行比较,错误复现,STL容器的长度类型为无符号型,最高位解释为数据位。所以当int类型的i为0,与无符号类型的s.size()-1进行比较时,肯定会一直比较下去。
可以在判断语句中加入&&s.size(),即仅当串非空串时进行操作。
for(int i=0;i<s.size()-1&&s.size(); ){
}
或者直接将s.size()强制转换为int,解决很多问题。
for(int i=0;i<(int)s.size()-1; ){
}
第四,关于给的数据类型
注意题目中对于数据的描述字眼,数据是正数positive,还是正整数positive integer,如果只是说是正数positive,最好用double来存储,因为可能有的测试样例卡的是数据类型。例如PATA1070 Mooncake 。
一定要非常小心double类型数据的比较操作。因为其在内存中是存储的IEEE754标准,double类型的运算涉及对阶,左右规,精度只有23+1=24位。所以一些判断条件是double类型的数的时候,要非常小心。