C++ 应用哪种数据结构?
有一个大小为C++ 应用哪种数据结构?,c++,data-structures,C++,Data Structures,有一个大小为n*n的矩阵,其中n这很有趣,它当然取决于要执行的操作数,但我会将其保存为两个一维数组。一个具有行输入,另一个具有列输入 行[n]和列[n] 因此,当您想知道say元素(4,7)的值时,它应该是行[4]+列[7],您可能需要一个用户定义的类型,该类型内部包含一个std::list 但实际上,你能同时在内存中保存25000000000个整数吗?我怀疑 您可能需要使用一种非常不同的、文件到内存映射的二维整数数组数据结构。进一步理解@Techmonk的答案:我提出两种方法: 1.Techm
n*n
的矩阵,其中n这很有趣,它当然取决于要执行的操作数,但我会将其保存为两个一维数组。一个具有行输入,另一个具有列输入
行[n]和列[n]
因此,当您想知道say元素(4,7)的值时,它应该是行[4]+列[7],您可能需要一个用户定义的类型,该类型内部包含一个std::list
但实际上,你能同时在内存中保存25000000000个整数吗?我怀疑
您可能需要使用一种非常不同的、文件到内存映射的二维整数数组数据结构。进一步理解@Techmonk的答案:我提出两种方法:
1.Techmonk's
O(1)用于更新,O(n^2)用于恢复0的数量
class matZeroCount {
std::vector< int > m_rows;
std::vector< int > m_cols;
public:
matZeroCount( unsigned int n ): m_rows( n, 0 ), m_cols( n, 0 ) {};
void updateRow( unsigned int idx, int update ) {
// check idx range w.r.t m_rows.size()
// ignore update == 0 case
m_rows[ idx ] += update;
}
void updateCol( unsigned int idx, int update ) {
// check idx range w.r.t m_cols.size()
// ignore update == 0 case
m_cols[ idx ] += update;
}
unsigned int countZeros() const {
unsigned int count = 0;
for ( auto ir = m_rows.begin(); ir != m_rows.end(); ir++ ) {
for ( auto ic = m_cols.begin(); ic != m_cols.end(); ic++ ) {
count += ( ( *ir + * ic ) == 0 );
}
}
return count;
}
};
类matZeroCount{
std::vectorm_行;
std::vectorm_cols;
公众:
matZeroCount(unsigned int n):m_行(n,0),m_列(n,0){};
void updateRow(无符号整数idx,整数更新){
//检查idx范围w.r.t m_行。大小()
//忽略更新==0大小写
m_行[idx]+=更新;
}
void updateCol(unsigned int idx,int update){
//检查idx范围w.r.t m_cols.尺寸()
//忽略更新==0大小写
m_cols[idx]+=更新;
}
无符号整数countZeros()常量{
无符号整数计数=0;
对于(自动ir=m_行。开始();ir!=m_行。结束();ir++){
对于(自动ic=m_cols.begin();ic!=m_cols.end();ic++){
计数+=((*ir+*ic)==0);
}
}
返回计数;
}
};
2.快速计数
此方法允许O(1)用于恢复零的数量,每次更新的代价为O(n)。如果您期望的更新少于O(n),那么这种方法可能更有效
class matZeroCount {
std::vector< int > m_rows;
std::vector< int > m_cols;
unsigned int m_count;
public:
matZeroCount( unsigned int n ): m_rows( n, 0 ), m_cols( n, 0 ), count(0) {};
void updateRow( unsigned int idx, int update ) {
// check idx range w.r.t m_rows.size()
// ignore update == 0 case
m_rows[ idx ] += update;
for ( auto ic = m_cols.begin(); ic != m_cols.end(); ic++ ) {
m_count += ( ( m_rows[ idx ] + *ic ) == 0 ); // new zeros
m_count -= ( ( m_rows[ idx ] - update + *ic ) == 0 ); // not zeros anymore
}
}
void updateCol( unsigned int idx, int update ) {
// check idx range w.r.t m_cols.size()
// ignore update == 0 case
m_cols[ idx ] += update;
for ( auto ir = m_rowss.begin(); ir != m_rows.end(); ir++ ) {
m_count += ( ( m_cols[ idx ] + *ir ) == 0 ); // new zeros
m_count -= ( ( m_cols[ idx ] - update + *ir ) == 0 ); // not zeros anymore
}
}
unsigned int countZeros() const { return m_count; };
};
类matZeroCount{
std::vectorm_行;
std::vectorm_cols;
无符号整数m_计数;
公众:
matZeroCount(unsigned int n):m_行(n,0),m_列(n,0),计数(0){};
void updateRow(无符号整数idx,整数更新){
//检查idx范围w.r.t m_行。大小()
//忽略更新==0大小写
m_行[idx]+=更新;
对于(自动ic=m_cols.begin();ic!=m_cols.end();ic++){
m_count+=((m_行[idx]+*ic)=0);//新的零
m_count-=((m_rows[idx]-update+*ic)==0);//不再是零
}
}
void updateCol(unsigned int idx,int update){
//检查idx范围w.r.t m_cols.尺寸()
//忽略更新==0大小写
m_cols[idx]+=更新;
对于(自动ir=m_rows.begin();ir!=m_rows.end();ir++){
m_count+=((m_cols[idx]+*ir)=0);//新的零
m_count-=((m_cols[idx]-update+*ir)==0);//不再是零
}
}
无符号整数countZeros()常量{return m_count;};
};
是一种适用于主要由零填充的矩阵的数据结构。其实施旨在提高空间效率。它适用于像您这样的情况,当您的矩阵很大且信息很少时。。更新是指+N还是设置为N?行/列是否可以重置为零?在第一种情况下,您也可以计算O(n)中的零数,答案应该是=NumZeros(行)*NumZeros(列)@Techmonk-我不确定我是否遵循了你的建议。如果我假设update
可以是负数(也可以是正数),那么我不需要明确地检查所有n^2
选项吗?因为最终总计只起作用,我们存储该行的总计,它应该不起作用,例如,想象一下我们为第1、2、2、3、1-2、2-2行得到一个3x3数组。然后我们将数组设为-1,0,1,假设列的值为-1,0,1,因此零的总数为count(row)*count(col)=1@Techmonk(1)我猜你的意思是11,22,33,1-2,2-2,3-2。(2) 以你的例子来说,结果矩阵不是[-2-10;-1 0 1;0 1 2],总计数=3吗?是的,你是对的,我没有正确地看待负案例。。它将是n^2
10 10 10
0 0 0
0 0 0
class matZeroCount {
std::vector< int > m_rows;
std::vector< int > m_cols;
public:
matZeroCount( unsigned int n ): m_rows( n, 0 ), m_cols( n, 0 ) {};
void updateRow( unsigned int idx, int update ) {
// check idx range w.r.t m_rows.size()
// ignore update == 0 case
m_rows[ idx ] += update;
}
void updateCol( unsigned int idx, int update ) {
// check idx range w.r.t m_cols.size()
// ignore update == 0 case
m_cols[ idx ] += update;
}
unsigned int countZeros() const {
unsigned int count = 0;
for ( auto ir = m_rows.begin(); ir != m_rows.end(); ir++ ) {
for ( auto ic = m_cols.begin(); ic != m_cols.end(); ic++ ) {
count += ( ( *ir + * ic ) == 0 );
}
}
return count;
}
};
class matZeroCount {
std::vector< int > m_rows;
std::vector< int > m_cols;
unsigned int m_count;
public:
matZeroCount( unsigned int n ): m_rows( n, 0 ), m_cols( n, 0 ), count(0) {};
void updateRow( unsigned int idx, int update ) {
// check idx range w.r.t m_rows.size()
// ignore update == 0 case
m_rows[ idx ] += update;
for ( auto ic = m_cols.begin(); ic != m_cols.end(); ic++ ) {
m_count += ( ( m_rows[ idx ] + *ic ) == 0 ); // new zeros
m_count -= ( ( m_rows[ idx ] - update + *ic ) == 0 ); // not zeros anymore
}
}
void updateCol( unsigned int idx, int update ) {
// check idx range w.r.t m_cols.size()
// ignore update == 0 case
m_cols[ idx ] += update;
for ( auto ir = m_rowss.begin(); ir != m_rows.end(); ir++ ) {
m_count += ( ( m_cols[ idx ] + *ir ) == 0 ); // new zeros
m_count -= ( ( m_cols[ idx ] - update + *ir ) == 0 ); // not zeros anymore
}
}
unsigned int countZeros() const { return m_count; };
};