程序终止:使用向量集的向量

Program killed: using vector of set of vector

本文关键字:向量 终止 程序      更新时间:2023-10-16

在我的算法中,我需要保留(3字节)扩展ASCII字符的所有组合。以下是我的代码,但当我运行此代码时,当最后一步发生时,程序在终端上被终止(BigVector.prustback)。为什么会这样?在我的情况下,有什么替代方案?

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)}}

请注意256^3=16777216。这是巨大的,尤其是当你使用向量和集合的时候!

因为您只需要记录256=2^8的信息,所以可以将其存储在一个字符(一个字节)中。您可以将每个组合存储在一个由三个字符组成的元组中。内存现在为16777216/1024/1024=16 MB。在我的电脑上,它在1秒内完成。

如果您接受C++11,我建议使用std::array,而不是在旧代码中编写像Info这样的辅助结构。

C++11代码使用std::array。

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;
}

首先:您的示例与实际代码不一致。您正在创建({(a,a,a),…,(z,z,z)})

如前所述,您将有16'777'216个不同的矢量。由于矢量对象的原因,每个矢量将包含3个字符,通常约20字节[1]的开销。

此外,一个典型的矢量实现将为未来的push_backs保留内存。

您可以通过在初始化期间指定正确的大小或使用reserve():来避免这种情况

vector<int> temp(3);

(capacity()告诉你矢量的"实际"大小)

pushback会复制您正在推送的对象[2],这可能会占用太多内存,从而导致程序崩溃。

16'777'216*(3个字符+20个开销)*2个副本=约736MiB
(这假设矢量已经用正确的大小初始化!)

有关复制问题的可能解决方案,请参见[2]。

我同意Potatoswatter的观点:你的数据结构效率很低。

[1] 空向量的开销是多少
[2]std::vector是否使用push_back复制对象?