1、定义数组的时候没有初始化,
不要尝试读出以及操作数组元素,否则会出现意想不到的错误;
回顾数组定义与初始化的问题:
C++中内置类型的数组定义后,数组元素的值是随机的;
如果数组在定义的时候使用花括号给出的常量值表且给定的常数的个数不足,则系统会对其余元素初始化为0值。
例子:
int a[3]={0,1}等价于 int a[3]={0,1,0}
string s[3]={“hi”,“bye”}等价于 string s[3]={“hi”,“bye”,“”}
典例:
class Solution {
public:
string getHint(string secret, string guess) {
int s[10];int g[10];
int A=0,B=0;
int len=int(secret.size());
for(int i=0;i<len;i++){
if(secret[i]==guess[i])A++;
else{
s[secret[i]-'0']++;g[guess[i]-'0']++;
}
}
for(int i=0;i<10;i++)B+=min(s[i],g[i]);//此处使用了未初始化的数组内存
return to_string(A)+"A"+to_string(B)+"B";
}
};
报错:
修改方案1:
class Solution {
public:
string getHint(string secret, string guess) {
int s[10]={0};int g[10]={0};//定义数组的时候初始化所有元素
int A=0,B=0;
int len=int(secret.size());
for(int i=0;i<len;i++){
if(secret[i]==guess[i])A++;
else{
s[secret[i]-'0']++;g[guess[i]-'0']++;
}
}
for(int i=0;i<10;i++)B+=min(s[i],g[i]);
return to_string(A)+"A"+to_string(B)+"B";
}
};
修改方案2:
class Solution {
public:
string getHint(string secret, string guess) {
int bulls = 0;
vector<int> cntS(10), cntG(10);//使用vector
for (int i = 0; i < secret.length(); ++i) {
if (secret[i] == guess[i]) {
++bulls;
} else {
++cntS[secret[i] - '0'];
++cntG[guess[i] - '0'];
}
}
int cows = 0;
for (int i = 0; i < 10; ++i) {
cows += min(cntS[i], cntG[i]);
}
return to_string(bulls) + "A" + to_string(cows) + "B";
}
};
拓展:通常情况下,可以只提供vector对象的元素数量而不用初始值,会根据vector对象的元素类型决定初始值,eg:int型元素初始值为0,string类型由默认初始化。
2、数组,vector等在循环中未考虑到越界情况问题:
典例:
报错程序代码:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int len=nums.size();
int l=-1,r=-1;
for(int i=0;i<len;i++){
if(nums[i]==target){
l=i;r=l;
while(nums[r]==target)r++;//此处未考虑到nums[r]可能越界
r--;
break;
}
} return vector<int>{l,r};
}
};
修改之后:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int len=nums.size();
int l=-1,r=-1;
for(int i=0;i<len;i++){
if(nums[i]==target){
l=i;r=l;
while(r<len&&nums[r]==target)r++;//注意,此处必须是r<len的范围判断在前,读取nums[r]在后(利用了逻辑判断的特性)
r--;
break;
}
}
return vector<int>{l,r};
}
};
3、关于c++ vector为空,size() - 1的坑
vector的size()函数返回的是一个无符号整数,当size() == 0,再减1,会导致溢出,从而使数据变大(16条消息) c++ vector为空,size() - 1的坑_h799710的博客-CSDN博客_空vector的sizehttps://blog.csdn.net/h799710/article/details/109445906
4、尽量用new/delete代替malloc/free
new/delete在管理内存的同时调用了构造和析构函数;而malloc/free仅仅实现了内存分配与释放
请记住:
(1) 不要企图用malloc/free 来完成动态对象的内存管理,应该用new/delete。
(2)请记住:new是C++的,而malloc是c的。如果混淆了它们,那将是件蠢事。所以new/delete必须配对使用,malloc/free也一样。(20条消息) 改善C++ 程序的150个建议学习之建议21:尽量用new/delete代替malloc/free_CodingAdo-CSDN博客https://blog.csdn.net/baliguan163/article/details/11554475?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1.no_search_link&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1.no_search_link
5、基于范围的for循环
基于范围的for循环中可通过引用修改数组元素中的值,直接修改只是修改副本,原始数组数据不变。
6、vector 使用之后没有及时清空
很多时候一个编程题目会有很多轮循环,每一轮循环执行完成之后,要记得及时清空某个在循环外定义的vector变量,否则后面的循环会受到前面循环留下的脏数据的影响
vector清空数据:clear() 方法