提问一个有关字符串的有关问题
提问一个有关字符串的问题
下面的程序为什么不能运行。
#include<iostream>
using std::cout;
using std::endl;
#include<vector>
using std::vector;
#include<string>
using std::string;
#include<algorithm>
using std::for_each;
vector<string> generator0_1(size_t n)
{
vector<string>out;
vector<string>require;
out.push_back("0");
out.push_back("1");
size_t i=0;
while(i<n-1)
{
if(i>0)
out=require;
size_t s0=out.size();
vector<string>::iterator pre_begin=out.begin();
auto pre_end=out.end();
while(pre_begin!=pre_end)
{
string temp0=*pre_begin+"0";
string temp1=*pre_begin+"1";
out.push_back(temp0);
out.push_back(temp1);
pre_begin++;
}
require.clear();
for(size_t i=s0;i<out.size();i++)
require.push_back(out[i]);
i++;
}
return require;
}
int main()
{
vector<string> v0=generator0_1(8);
for_each(v0.begin(),v0.end(),[](const string&s){cout<<s<<endl;});
cout<<endl;
return 0;
}
------解决思路----------------------
楼主改成:
vector<string> generator0_1(size_t n)
{
vector<string>out;
vector<string>require;
out.push_back("0");
out.push_back("1");
size_t i=0;
while(i<n-1)
{
if(i>0)
out=require;
size_t s0=out.size();
vector<string>::iterator pre_begin=out.begin();
vector<string>::iterator pre_end=out.end();
while(pre_begin!=pre_end)
{
string temp0=*pre_begin+"0";
string temp1=*pre_begin+"1";
out.push_back(temp0);
out.push_back(temp1);
pre_begin++;
}
require.clear();
for(size_t i=s0;i<out.size();i++)
require.push_back(out[i]);
i++;
}
return require;
}
void print(const string& s)
{
cout<<s<<endl;
}
int main()
{
vector<string> v0=generator0_1(8);
for_each(v0.begin(),v0.end(),print);
cout<<endl;
return 0;
}
这样编译可能没有问题,但运行可能会有问题,vector容器在使用时,当压入的数据大于它的容量时,就会重新开辟一块更大内存,并将数据拷贝到新内存中,原先的数据就被释放掉了,所以,在迭代时,往容器插入数据,会导致迭代器失效,即程序中pre_begin和pre_end成为野指针,这样在访问时,程序可能会崩溃
------解决思路----------------------
为什么非要用iterator?课程要求?
------解决思路----------------------
在使用iterator时,一定要注意其有效性
比如vector的push_back会使之前的end失效,所以你的程序一定会出问题
非要用iterator的话,
可以考虑再用个容器来接收枚举产生的结果,
也可以考虑使用list这类不会使iterator失效的容器:
下面的程序为什么不能运行。
#include<iostream>
using std::cout;
using std::endl;
#include<vector>
using std::vector;
#include<string>
using std::string;
#include<algorithm>
using std::for_each;
vector<string> generator0_1(size_t n)
{
vector<string>out;
vector<string>require;
out.push_back("0");
out.push_back("1");
size_t i=0;
while(i<n-1)
{
if(i>0)
out=require;
size_t s0=out.size();
vector<string>::iterator pre_begin=out.begin();
auto pre_end=out.end();
while(pre_begin!=pre_end)
{
string temp0=*pre_begin+"0";
string temp1=*pre_begin+"1";
out.push_back(temp0);
out.push_back(temp1);
pre_begin++;
}
require.clear();
for(size_t i=s0;i<out.size();i++)
require.push_back(out[i]);
i++;
}
return require;
}
int main()
{
vector<string> v0=generator0_1(8);
for_each(v0.begin(),v0.end(),[](const string&s){cout<<s<<endl;});
cout<<endl;
return 0;
}
------解决思路----------------------
楼主改成:
vector<string> generator0_1(size_t n)
{
vector<string>out;
vector<string>require;
out.push_back("0");
out.push_back("1");
size_t i=0;
while(i<n-1)
{
if(i>0)
out=require;
size_t s0=out.size();
vector<string>::iterator pre_begin=out.begin();
vector<string>::iterator pre_end=out.end();
while(pre_begin!=pre_end)
{
string temp0=*pre_begin+"0";
string temp1=*pre_begin+"1";
out.push_back(temp0);
out.push_back(temp1);
pre_begin++;
}
require.clear();
for(size_t i=s0;i<out.size();i++)
require.push_back(out[i]);
i++;
}
return require;
}
void print(const string& s)
{
cout<<s<<endl;
}
int main()
{
vector<string> v0=generator0_1(8);
for_each(v0.begin(),v0.end(),print);
cout<<endl;
return 0;
}
这样编译可能没有问题,但运行可能会有问题,vector容器在使用时,当压入的数据大于它的容量时,就会重新开辟一块更大内存,并将数据拷贝到新内存中,原先的数据就被释放掉了,所以,在迭代时,往容器插入数据,会导致迭代器失效,即程序中pre_begin和pre_end成为野指针,这样在访问时,程序可能会崩溃
------解决思路----------------------
为什么非要用iterator?课程要求?
------解决思路----------------------
在使用iterator时,一定要注意其有效性
比如vector的push_back会使之前的end失效,所以你的程序一定会出问题
非要用iterator的话,
可以考虑再用个容器来接收枚举产生的结果,
也可以考虑使用list这类不会使iterator失效的容器:
ist<string> generator0_1(size_t n)
{
list<string> out = { "" };
list<string> require;
size_t i = 0;
while (i++ < n)
{
auto pre_begin = out.begin();
auto pre_end = out.end();
while (pre_begin != pre_end)
{
out.insert(pre_begin, *pre_begin + "0");
*pre_begin += '1';
++pre_begin;
}
require.insert(require.end(), out.begin(), out.end());
}
return require;
}