- 1.再探substr的保险使用方法
今天上午写电话号码,死活有数据不过,最后找助教要了一组没过的数据测试了下,发现了奇怪的现象
使用默认参数的substr(size_t start , size_t length)实现
string substr (size_t pos = 0, size_t len = npos) const;
我的用法是:
string result = str.substr(Found );
照理说因该自动复制到末尾并构造出最大值
但是,神奇的现象是
这个库函数有bug!!!!!!!!!!!!!!!!!
当我的Found(使用find方法返回的坐标)出现刚好和str最后下标相同时,substr函数停止了工作:
#include <bits/stdc++.h>
using namespace std;
struct Peo{
string na;
int num;
vector <string> list;
};
bool compare(Peo p1 , Peo p2);
bool compare1(string s1,string s2);
int main(){
set <string> S;
vector <Peo> vec;
int n;
cin >> n;
string name;
int temp_n;
string temp_str;
for(int i = 0 ; i < n ; i++){
cin >> name;
if(!S.count(name)){
cout << "a new name " << name << endl;
Peo* p = new Peo;
p->na = name;
p->num = 0;
vec.push_back(*p);
S.insert(name);
}
cout << "name inserted" << endl;
for(vector <Peo> :: iterator it = vec.begin() ; it != vec.end() ; it++){
if((*it).na == name){
cout << "find the guy " << name << " updata now" << endl;
cout << "tell me how many numbers you wanna insert this time " << endl;
cin >> temp_n;
for(int j = 0 ; j < temp_n ; j++){
cout << "tell me the " << j + 1 << " num :" << endl;
cin >> temp_str;
cout << "try to insert number " << temp_str << endl;
int len_temp = temp_str.size();
cout << "its length == " << len_temp << endl;
if((*it).num == 0){
cout << "it's the first time to insert new number " << endl;
(*it).list.push_back(temp_str);
(*it).num++;
cout << "now number of" << name << " = " << (*it).num << endl;
continue;
}
cout << "it's not the first time to insert a number " << endl;
bool in_list = false; //开始假设不在其中
cout << "begin to check all current numbers " << endl;
for(vector <string> :: iterator it1 = (*it).list.begin() ; it1!= (*it).list.end() ; it1++){
cout << "now check the current num of " << (*it).na << endl;
int len_of_current_str = (*it1).size();
cout << "temp_str = " << temp_str << endl;
cout << "len of current str = " << len_of_current_str << endl;
cout << "the str in list that be checkded now : " << *it1 << endl;
if(len_temp >= len_of_current_str){
cout << "len_of_temp > *it begin to check if it can include the *it" << endl;
size_t Found = temp_str.find((*it1));
if(Found != std::string::npos){
if((*it1) == temp_str.substr(Found,len_of_current_str)){//使用默认构造参数,直接构造到末尾
cout << "yes it can include the str " << endl;
(*it1) = temp_str;
cout << "now begin to repalce it" << endl;
in_list = true;//包含其中某个字符串,替换成更大的
cout << "now *it == " << (*it1) << endl;
break;
}
}
}
else{
cout << "len < *it" << endl;
size_t Found = (*it1).find(temp_str);
if(Found != std::string::npos){
if(temp_str == (*it1).substr(Found,len_temp)){//使用默认构造参数,直接构造到末尾
cout << "is included , will not insert it" << endl;
in_list = true;//在其中
break;
}
}
}
}
if(in_list == false){
cout << "it's not in the list , begin to insert " << endl;
(*it).num++;
(*it).list.push_back(temp_str);
cout << "number has been inserted , now there are " << (*it).num << "tele numbers" << endl;
}
}
}
}
}
sort(vec.begin(),vec.end(),compare);
for(vector <Peo> :: iterator it = vec.begin() ; it != vec.end() ; it++){
sort((*it).list.begin(),(*it).list.end(),compare1);
cout << (*it).na << " " << (*it).num << " ";
for(vector <string> :: iterator it1 = (*it).list.begin() ; it1 != (*it).list.end() ; it1++){
cout << (*it1);
if(it1 != (*it).list.end()-1){
cout << " ";
}
}
cout << endl;
}
return 0;
}
bool compare(Peo p1 , Peo p2){
return p1.na < p2.na;
}
bool compare1(string s1,string s2){
int size1 = s1.size();
int size2 = s2.size();
if(size1 != size2){
return size1 < size2;
}
return s1 < s2;
}
这是修改后的版本,以后再也不敢乱用默认参数了,搞不好就被卡掉一半数据
if((*it1) == temp_str.substr(Found,len_of_current_str)){//使用默认构造参数,直接构造到末尾
if(temp_str == (*it1).substr(Found,len_temp)){//使用默认构造参数,直接构造到末尾
就改了这两句,开始没加len_of_current_str参数和len_temp参数,错到怀疑人生,知道我每一句话都加上cout当前变量值开始运行才发现2并不能被32覆盖,以及32不能被332覆盖,才意识到很可能是这个库函数本身有问题
然后我就加上了两个参数,然后输出就正确了
修改substr写法,不使用默认参数后:
这是修改之后的运行结果:
当然这个题目这么写逻辑有问题(因为find函数的返回值是最先找到的数据对应的下标),已经将逻辑修改正确,就不粘代码了