在我的算法中,我需要保留(3个字节)扩展ASCII字符的所有组合。以下是我的代码但是当我运行这段代码时,程序会在最后一步发生时在终端上被杀死(BigVector.pushback)。为什么这样,在我的情况下可以选择什么呢?
vector<set<vector<int> > > BigVector;
set<vector<int> > SmallSet;
for(int k=0; k <256; k++)
{
for(int j=0; j <256; j++)
{
for(int m=0; m <256; m++)
{
vector<int> temp;
temp.push_back(k);
temp.push_back(j);
temp.push_back(m);
SmallSet.insert(temp);
}
}
}
BigVector.push_back(SmallSet);
P.S:我必须像这样保留ascii字符: {{(a,b,c),(a,b,d),......(z,z,z)}}
答案 0 :(得分:2)
请注意 256 ^ 3 = 16,777,216 。这是巨大的,特别是当你使用vector和set!
时因为您只需要记录256 = 2 ^ 8个信息,所以可以将其存储在char(一个字节)中。您可以将每个组合存储在三个字符的一个元组中。内存现在为16,777,216 / 1024/1024 = 16 MB 。在我的计算机上,它以 1 秒结束。
如果您接受C ++ 11,我建议使用std::array
,而不是在我的旧代码中编写像Info
这样的辅助结构。
使用std :: array的C ++ 11代码。
vector<array<char,3>> bs;
.... for loop
array<char,3> temp;
temp[0]=k; temp[1]=j; temp[2]=m;
bs.push_back(temp);
使用自制结构的C ++ 98代码。
struct Info{
char chrs[3];
Info ( char c1, char c2, char c3):chrs({c1,c2,c3}){}
};
int main() {
vector<Info> bs;
for (int k = 0; k < 256; k++) {
for (int j = 0; j < 256; j++) {
for (int m = 0; m < 256; m++) {
bs.push_back(Info(k,j,m));
}
}
}
return 0;
}
使用这些组合的方法。 (您可以为Info编写包装器方法。)
// Suppose s[256] contains the 256 extended chars.
for( auto b : bs){
cout<< s[b.chrs[0]] << " " << s[b.chrs[1]] << " "<< s[b.chrs[2]] << endl;
}
答案 1 :(得分:2)
首先:您的示例与实际代码不符。 您正在创建({(a,a,a),...,(z,z,z)})
如前所述,您将拥有16'777'216种不同的载体。由于矢量对象,每个向量将保持3个字符,通常约为20个字节[1]。
此外,典型的矢量实现将为将来的push_backs保留内存。
您可以通过在初始化期间指定正确的大小或使用reserve()来避免这种情况:
vector<int> temp(3);
(capacity()告诉你矢量的“真实”大小)
push_back会复制你正在推送的对象[2],这可能是内存过多而导致你的程序崩溃。
16'777'216 *(3个字符+ 20个开销)* 2个拷贝= ~736MiB。
(这假设向量已经用正确的大小初始化了!)
有关复制问题的可能解决方案,请参阅[2]。
我同意Potatoswatter:您的数据结构非常低效。
[1] What is the overhead cost of an empty vector?
[2] Is std::vector copying the objects with a push_back?