假设我们已经阅读了这些值:
3
1241
124515
5322353
341
43262267234
1241
1241
3213131
我有一个这样的数组(包含上面的元素):
a[0]=1241
a[1]=124515
a[2]=43262267234
a[3]=3
...
问题是数组中的元素顺序不是常数(我必须在程序的其他地方更改它)。
我如何知道一个元素在阅读文档中出现的位置。
请注意,我不能这样做:
vector <int> a[1000000000000];
a[number].push_back(all_positions);
因为a太大(存在内存限制)。 (假设我只有3000个元素,但它们的值是从0到2 ^ 32)
所以,在上面的例子中,我想知道1241出现的所有位置,而不再遍历所有读取元素。
换句话说,如何将数字“1241”与位置“1,6,7”相关联,这样我就可以在O(1)中简单地访问它们(其中1实际上是元素出现的位置数)
如果没有O(1)我想知道什么是最佳的...... 我不知道我是否已经说清楚了。如果没有,请说出来,我会更新我的问题:)
答案 0 :(得分:3)
你需要使用某种动态数组,比如矢量(std::vector
)或其他类似的容器(std::list
,也许,这取决于你的需要)。
这样的数据结构比C风格的数组更安全,更容易使用,因为它们负责内存管理。
如果您还需要在O(1)中查找元素,则应考虑使用一些将索引与项目和项目关联到索引的结构。我不认为STL会提供任何东西,但是提升应该有类似的东西。
如果O(log n)是您可以承受的成本,也请考虑std::map
答案 1 :(得分:2)
您可以使用通常称为multimap的内容。也就是说,它存储Key和多个值。这是一个O(日志)查找时间。
如果您正在使用Visual Studios,他们会提供自己的hash_multimap,否则我建议您使用Boost::unordered_map并将列表作为您的值?
答案 2 :(得分:2)
您不需要100,000000000个元素的稀疏数组;使用std::map
将位置映射到值。
如果你想要双向查找(也就是说,你有时想要“这个值的索引是什么?”,有时候“这个索引的值是多少?”)那么你可以使用boost::bimap
。
由于您的值不止一次出现,事情变得更加复杂。您可以牺牲双向查找并使用std::multimap
。
答案 3 :(得分:2)
您可以使用地图。像:
std::map<int, std::vector<int>> MyMap;
因此,每次在阅读文件时遇到值,都会将其位置附加到地图上。假设X是您读取的值,Y是您刚刚执行的位置
MyMap[X].push_back( Y );
答案 4 :(得分:2)
而不是你使用数组
std::map<int, vector<int> > a;
答案 5 :(得分:2)
您需要一个关联集合,但您可能希望与多个值相关联。
您可以使用std::multimap< int, int >
或
您可以使用std::map< int, std::set< int > >
我在实践中发现,如果您只需要删除一个元素,后者更容易删除项目。它在键值组合上是独一无二的,但不仅仅是键或值。
如果您需要更高的性能,那么您可能希望使用hash_map而不是map。对于内部集合虽然在使用哈希时不会有太多的性能,因为你将只有很少的重复,并且它最好是std :: set。
hash_map有很多实现,它在新标准中。如果您没有新标准,请选择加强。
答案 6 :(得分:1)
您似乎需要std::map<int,int>
。您可以存储映射,例如1241->0
124515->1
等。然后在此映射上执行查找以获取数组索引。
答案 7 :(得分:1)
您可以使用std::multimap来存储密钥(例如1241)和多个值(例如1,6和7)。
insert具有对数复杂度,但如果您为插入方法提供可以插入项目的提示,则可以加快速度。
答案 8 :(得分:1)
除了其他人提供的std::map
解决方案(O(log n))之外,还有哈希映射的方法(在C ++ 0x中实现为boost::unordered_map
或std::unordered_map
,由现代编译器支持。)
它会为您提供平均的O(1)查找,often比基于树的std::map
更快。试试吧。
答案 9 :(得分:1)
对于O(1)查找,您可以散列数字以在哈希映射中找到其条目(键)(boost :: unordered_map,dictionary,stdex :: hash_map等)
该值可以是数字出现的索引向量,也可以是3000位数组(375字节),其中设置了数字(键)出现的每个相应索引的位数。
boost::unordered_map<unsigned long, std::vector<unsigned long>> myMap;
for(unsigned long i = 0; i < sizeof(a)/sizeof(*a); ++i)
{
myMap[a[i]].push_back(i);
}
答案 10 :(得分:0)
您可以存储一个包含整数值及其所有位置的结构数组,而不是存储整数数组。