如何在c ++中创建一个包含2个循环的完整矩阵

时间:2012-01-24 00:57:44

标签: c++ matrix transform

我在c ++中有一个字符串,它代表一个上三角矩阵,我想做的是从这个字符串中修整一个完整的矩阵

    std::string input = "1,2,1,3,6,1,4,7,9,1";
    //this represents


 //1  2  3 4
 //2  1  6 7
 //3  6  1 9
 //4  7  9 1

std::replace(input.begin(), input.end(), ',', ' ');
std::vector<double> Matrix;
std::istringstream inputStream(input);
double value;
int rowNum = 0;
int colNum = 0; 

while (inputStream >> value){
    for (colNum = 0; colNum < 2; colNum++){
        if (colNum >= rowNum){
            Matrix.push_back( value ); 
        }
        else{
            Matrix.push_back( Matrix[colNum * 2 + rowNum]); 
        }
    }

    rowNum++;
}
inputStream >> std::ws;

而不是

 1  2  3 4
 2  1  6 7
 3  6  1 9
 4  7  9 1

但我得到了

   1.0000   1.0000   1.0000   2.0000
   1.0000   1.0000   2.0000   1.0000
   1.0000   2.0000   1.0000   1.0000
   2.0000   1.0000   1.0000   2.0000

我的错误是什么?我看不出来......

2 个答案:

答案 0 :(得分:1)

您应该显示用于打印输出的索引方案(即您希望索引如何工作):您选择使用向量而不是矩阵会使代码难以纠正。当然,我看到以下与输入模式没有明确联系的要点:

1)您读取的每个数字都会增加rowNum索引。该行应该在“步骤”1,1 + 2,1 + 2 + 3,...

处递增

2)colNum的范围应为0到当前rowNum,而不是假设为0

3)在你阅读之前没有机会填写一行(比如第一行)(比如说最后一个)。如果输入为1 2 3 4 1 6 7 1 9 1

,则可以执行此操作

所有这些点都是相关的,并且来自错误的数据表示,这使得难以完成一项微不足道的任务。

在C ++中,解决这些问题的一种非常有效的方法是数据隐藏:考虑我们如何轻松编写一个提供正确逻辑表示的类并且不会浪费空间:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>

template <class T = double>
class upper_triangular_matrix
{
    std::vector<T> Matrix;

public:

    upper_triangular_matrix(std::string input)
    {
        // trade time for space: store the values, compute indexing
        std::replace(input.begin(), input.end(), ',', ' ');
        std::istringstream inputStream(input);
        T value;
        while (inputStream >> value)
            Matrix.push_back(value);

        // validate size: ok 1,1+2,1+2+3 etc
    }

    T operator()(int r, int c) const
    {
        // compute indexing accounting for miss duplicated
        if (c > r)
            std::swap(c, r);
        int p = 0, n = 1;
        while (r > 0)
        {
            p += n++;
            r--;
        }
        return Matrix[p + c];
    }
};

int main()
{
    upper_triangular_matrix<> m("1,2,1,3,6,1,4,7,9,1");
    for (int r = 0; r < 4; ++r)
    {
        for (int c = 0; c < 4; ++c)
            std::cout << m(r, c) << ' ';
        std::cout << std::endl;
    }
}

运行时打印

1 2 3 4 
2 1 6 7 
3 6 1 9 
4 7 9 1 

答案 1 :(得分:0)

很难确切地知道错误的位置,但这里是它开始的地方:

std::vector<double> Matrix;

是的,带有std::vector<double>元素的非空n是一个矩阵:1xn或nx1矩阵(或两者)。但是,在您的上下文中,这种观点完全没有用。

当您阅读第一个元素时,让我们看看for - 循环:

  1. colNum == 0,rowNum == 0 =&gt; (1,1)= Matrix [0] = 1
  2. colNum == 1,rowNum == 0 =&gt; (2,1)= Matrix [1] = 1
  3. 这一开始显然是错误的。在此rowNum变为1之后:

    1. colNum == 0,rowNum == 1 =&gt; (3,1)=矩阵[2] =矩阵[colNum * 2 + rowNum] =矩阵[1] = 1
    2. colNum == 1,rowNum == 1 =&gt; (4,1)=矩阵[3] = 2
    3. 好吧,我想你可以自己写下剩余部分。当然,我可以快速编写代码来解决您的问题,但我认为这个小练习适合您。这样做的方法是使用转置矩阵中的值填充第一个row列(其中row是当前正在处理的行,使用常规索引,以0开头),然后从文件中读取剩余的n - row列(其中n是矩阵的大小)。