关联矩阵c++太大
Associative matrix c++ too big
减少矩阵大小的方法在哪里?(x2阵列)例如,我只需要将数据(0,1,2)存储到数组中但是元素可以高达25万。?有没有一种存储值的方法,比如在字典里?
const int MAX = 250000;
short data[MAX][MAX] = {};//wont compile..
正如我在上面评论的那样,这对我来说非常有效(住在这里):
#include <iostream>
#include <unordered_map>
std::unordered_map<unsigned int, std::unordered_map<unsigned int, unsigned char>> data;
int main() {
std::cout << "oi" << std::endl;
data[232432][234234] = 2;
data[2][2] = 1;
std::cout << int(data[232432][234234]) << std::endl;
std::cout << int(data[3][3]) << std::endl;
std::cout << int(data[232432][1]) << std::endl;
std::cout << int(data[2][2]) << std::endl;
}
我记得静态变量的大小有一些限制。使用动态内存。根据元素数量和内存限制,可以使用不同类型的存储。
- 当元素的数量小于某个预定义值时,换句话说,数据密度低时,可以使用稀疏矩阵。稀疏矩阵的思想很简单:不保留所有可能的元素;相反,您保留一些大量元素的普通数组,比如1000,类型为struct{int line,row;unsigned char value;}。在一定的数值上,这种数组的内存消耗小于矩阵。但这可能是随机访问的显著开销。可以应用一些优化来减少它
- 如果数据密度高,"活动"元素的数量大,则使用压缩矩阵、比特填充可以达到一定的效果。通过记忆,这可能非常有效。在您的示例中,每个值只需要2位,因此int64将在一个"行"中保留32个值。这里需要精细优化的访问方法来减少时间消耗
- 您可以在上述解决方案之间切换,以从稀疏矩阵迁移到压缩矩阵
如果数据非常稀疏,那么Massa的方法的开销是每个项目多出一个unordered_map
。一个较低开销的解决方案是用对对无序映射进行索引:
#include <iostream>
#include <unordered_map>
/// Hash specialization for a pair of unsigned ints
template<> struct std::hash<std::pair<unsigned int, unsigned int>>
{
typedef std::pair<unsigned int, unsigned int> argument_type;
typedef std::size_t value_type;
value_type operator()(argument_type const& s) const
{
value_type const h1 ( std::hash<unsigned int>()(s.first) );
value_type const h2 ( std::hash<unsigned int>()(s.second) );
return h1 ^ (h2 << 1);
}
};
std::unordered_map<std::pair<unsigned int, unsigned int>, unsigned char> data;
int main() {
using std::make_pair;
data[make_pair(232432u, 234234u)] = 2;
data[make_pair(2u, 3u)] = 1;
std::cout << int(data[make_pair(232432u, 234234u)]) << std::endl;
std::cout << int(data[make_pair(3u, 3u)]) << std::endl;
std::cout << int(data[make_pair(232432u, 1u)]) << std::endl;
std::cout << int(data[make_pair(2u, 3u)]) << std::endl;
}
压缩
您可以压缩数据值,这将节省内存,但会增加访问时间。
您的值范围:0,1,2,占用2位来表示。因此,一个8位的uint8_t变量可以包含4列值:
3 2 1 0
+--+--+--+--+
|xx|xx|xx|xx|
+--+--+--+--+
要访问这些值,您需要执行一些二进制运算:
value of column 0 == (byte & 0x03); /* >> 0 */
value of column 1 == (byte & 0x0c) >> 2;
value of column 2 == (byte & 0x30) >> 4;
value of column 3 == (byte & 0xC0) >> 6;
字节将通过以下方式访问:(index / 4)
视角的改变
由于只有3个值,因此可以将坐标存储在数组的列表中。您可以在数组中搜索坐标。
Data row col row col
+---+ +-----+----+ +-----+---+
| 0 | --> | 115 | 25 | --> |20961| 4 |
+---+ +-----+----+ +-----+---+
| 1 |
+---+
| 2 |
+---+
在上图中,矩阵位置[115][25]包含零,以及[20961][4]。
在上面的技术中,您可以通过使用范围来压缩矩阵位置。
相关文章:
- 当我的阵列太大时出现分段错误
- 为什么C++程序在太大时返回代码而不是答案?
- googletest:测试太大的数据结构
- 整数文本太大,无法用任何整数类型表示--C++
- C++ boost::multi_array索引太大
- 使用 MinGW 构建 ASSIMP 会导致文件太大错误
- 与WM_DPICHANGED消息一起发送的建议窗口大小太大
- 在 Cygwin G++ 上编译的文件太大
- iOS:添加静态库后C++应用大小太大
- 当小部件太大时,Gtk 3
- 将字符转换为ASCII返回数字太大
- 这个查找查询是否出错,因为我输入的数字太大
- 词频程序 - 文件输入太大?
- 将 32 位浮点数和不强制转换的 32 位整数与双精度进行比较,当其中一个值可能太大而无法完全适合另一种类型时
- 一个倒梯形,但如果输入高度对于宽度来说太大,那么它应该报告,不可能("不可能的形状"是什么)
- Pollard Rho 在不太大的输入上崩溃
- std::矢量容量变得太大了
- 在int到char转换期间,int将在char中存储在char中,如果int太大,将在char中存储的值
- 当偏移太大(大于签名的INT 2^32范围)时,GZSEEK(ZLIB)失败
- r包装中的对象文件太大(RCPP)