【问题标题】:How to make a complete matrix with 2 loops in c++如何在c ++中制作一个带有2个循环的完整矩阵
【发布时间】:2012-01-24 00:57:44
【问题描述】:

我在 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

我的错误是什么?看不到。。。

【问题讨论】:

    标签: c++ matrix transform


    【解决方案1】:

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

    1) 您读取的每个数字都会增加 rowNum 索引。该行应该在 'steps' 1、1+2、1+2+3、...

    2) colNum 的范围应该从 0 到当前 rowNum,而不是假设只有 0,1

    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 
    

    【讨论】:

      【解决方案2】:

      很难准确判断错误在哪里,但它是从这里开始的:

      std::vector<double> Matrix;
      

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

      让我们看一下阅读第一个元素时的for-loop:

      1. colNum == 0, rowNum == 0 => (1, 1) = Matrix[0] = 1
      2. colNum == 1, rowNum == 0 => (2, 1) = Matrix[1] = 1

      这个开始显然是错误的。在此之后rowNum 变为 1:

      1. colNum == 0, rowNum == 1 => (3, 1) = Matrix[2] = Matrix[colNum * 2 + rowNum] = Matrix[1] = 1
      2. colNum == 1, rowNum == 1 => (4, 1) = Matrix[3] = 2

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

      【讨论】:

      • 所以第一件事是将循环 for (colNum = 0; colNum &lt; 4; colNum++){ 更改为 4,因此它对列执行 4 次
      猜你喜欢
      • 1970-01-01
      • 2023-03-04
      • 2015-10-16
      • 2020-05-25
      • 2022-07-19
      • 2023-01-02
      • 2021-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多