如何创建具有用户指定维度的矩阵

时间:2016-09-26 23:21:31

标签: c++ arrays matrix

我需要根据用户的输入存储一些数据。我的程序应该根据我从cin获得的int值创建不同的数据结构。

例如,值0存储标量,1 - 向量,2 - 2dArray,3 - 3dArray,4 - 4d数组等等......

我的问题是,是否可以编写一些可以执行此操作的代码。

我知道这可能听起来令人困惑,所以我还会提供一些例子。

让我们说用户输入0 5,然后我的程序应该创建一个int变量并在其中存储5。

如果用户输入1 5,7,6,我的程序应该创建一个vector = {5,7,6};

如果用户输入2 2,3 1,2,3,4,5,6我的程序应该创建一个2d数组a [2] [3]并将值存储在那里。

如果我知道用户将拥有的最大维数,我可以找出解决方案,但分配的目标是可以指定任意数量的维度......

请帮助

3 个答案:

答案 0 :(得分:1)

  1. 您知道如何阅读用户输入吗?如果没有,首先要弄清楚如何在C ++中做到这一点。
  2. 从用户输入中读取一个变量,该变量将告诉您要创建的结构的类型。 (提示,使用int
  3. 使用适当的检查来查看用户输入的内容(提示,使用if() {} else if() {}等。
  4. 根据初始类型,构建适当的结构,提示创建所有类型,例如struct Scalar{}struct Vector{}等。
  5. 在您创建的每个结构中调用read()方法,以读取用户输入的其余部分。 (你需要使用某种形式的机制来分割用户输入,提示:字符串标记化)
  6. 拒绝您不支持的类型。

答案 1 :(得分:1)

如果你放松一些要求("根据我从cin&#34获得的int值创建不同的数据结构),这是可能的。这里只是一个草图,而不是一个完整的答案,但希望它会让你走上正轨。

访问存储空间

您需要将数字存储在所需类型的单个数组中,并通过索引映射函数包含对它们的访问。 例如,在2D中,一个这样的函数是

int indexIn2D(uint rowCol[2], int rowCount) {
  // rowCol[0] - is row index, rowCol[1] is col index
  return rowCol[0]*rowCount + rowCol[1];
}

float* values=new float[numRows*numCols];

// I want the element at (i,j)
float& myIJElement=values[indexIn2D({i,j}, numRows)];

将此转换为N维将需要

// suppose I'm storing a 3D matrix with [3 slices, 4 rows, 5 columns]
// as a 1D array and I want the element at [x,y,z] - what's it would be
// the position of that element in my 1D array?
// - fill coodIndex[3] with {x,y,z}
// - pass nDim=3
// - the dimSignature will be {3 /*slices*/, 4 /*rows*/, 5 /*columns*}
int indexInND(uint coordIndex[], uint numDim, uint[] dimSignature) {
   int ret=coordIndex[0];
   for(uint i=0; i<numDim-; i++) {
      ret=ret*dimSignature[i]+coordIndex[i+1];
   }
   return ret;
}

类似变体的存储类型

嗯,我们已经知道我们将存储整个&#34; N-dim块&#34;作为目标类型的unidim数组。所以我们可以使用指针并拥有我们的&#34;存储&#34;

之类的东西
struct NDimStorage {
  // 0 for int, 1 for float, etc.
  int whichType; // or make it enum
  union {
    int* int_st;
    float* float_st;
  };
  uint numDims;
  uint dimSignature[];
};

后退fom变体到std :: vector

类似的东西:

template <typename NumType> class VectNStorage {
   std::vector<NumType> storage;
   std::vector<uint> dimSignature;
protected:
   size_t indexMapping(const std::vector<uint>& indices) {
     size_t ret=indices[0];
     for(uint i=0; i<this->dimSignature.size()-1) {
       ret=ret*this->dimSignature[i]+indices[i+1];
     }
     return ret;
   }
public:
  VectNStorage(const std::vector<uint> dimsDef) : storage(), dimSignature(dimsDef) {
    uint howMany=1;
    for(auto d : this->dimSignature) {
      howMany*=d;
    }
    this->storage.resize(howMany);
    std::fill(this->storage.begin(), this->storage.end(), 0);
  }

  NumType& at(const std::vector<uint>& indices) {
    return this->storage[this->indexMapping(indices)];
  }
}

答案 2 :(得分:0)

您可以对所有类型的用户输入使用普通std::vector。你唯一需要的是一些函数f(x),它将把k-size的索引向量映射到plain数组中的索引。

例如:x-k大小的索引向量,s-k大小的维度大小向量

k = 1 -> f1(x,s) = x1;
k = 2 -> f2(x,s) = x2*s2 + x1;
k = 3 -> f3(x,s) = x3*s3*s2 + x2*s2 + x1 = x3*s3*s2 + f2(x2,x1,s2,s1);
k = 4 -> f4(x,s) = x4*s4*s3*s2 + f3(x3,x2,x1,s3,s2,s1);

最后一个坐标的乘数是(k-1)维对象的体积。 另外,我们认为,坐标的编号从0开始。

这看起来像递归函数,可以很容易实现。你只需要计算(k - 1)维对象的移位,从数组中弹出坐标,再从它自己调用函数。