c++ - C++ 中矩阵的用户输入

标签 c++ arrays string matrix token

我无法读取用户的输入并将其转换为矩阵进行计算。例如,对于 input = {1 2 3/4 5 6},程序应该以

的形式读入矩阵
1 2 3 
4 5 6

有 3 列和 2 行。到目前为止我得到的似乎不起作用:

input.replace(input.begin(), input.end(), '/', ' ');
    stringstream ss(input);
    string token;   
    while (getline(ss, token, ' '))
    {
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                int tok = atoi(token.c_str());
                (*matrix).setElement(i, j, tok);                
            }
        }
    }

所以我要做的是将输入分解为标记,并使用 setElement 函数将它们存储到矩阵中,该函数获取行数、列数和用户想要存储的变量。这段代码的错误在于 tok 的变量似乎没有改变并一直卡在 0 中。假设 row 和 col 是已知的。

非常感谢您的帮助。

最佳答案

虽然存在许多解决特定问题的简单方法(其他答案有各种好的建议),但让我尝试对“格式化输入”问题给出一个更一般的看法。

这里基本上存在三种问题:

  1. 在底层你必须做一个字符串到数字的转换
  2. 在更高层次上,您必须解析复合格式(理解行和行分隔)
  3. 最后,您还必须了解化合物的大小(有多少行和多少列?)

这 3 件事情并不完全独立,最后一件事情需要知道如何存储元素(如何调整矩阵的大小?)

最后是第 4 个问题(其他 3 个问题都存在):如果输入“错误”怎么办。

这类问题通常以两种相反的方式提供:

  1. 读取数据,识别格式是否匹配,并动态增长必须包含它们的数据结构或...
  2. 按原样读取所有数据(文本形式),然后分析文本以确定它有多少元素,然后隔离“ block ”并进行转换。

第 2 点需要良好的字符串操作,但也需要知道输入有多长的能力(如果其中一个分隔空格是换行符会发生什么?一切都通过 getline 得到的想法 在这些情况下失败)

第 1 点需要一个能够在您阅读时增长的 Matrix 类,或者一个临时的动态结构(例如和 std 容器),您可以在其中放置您阅读的内容在将其发送到适当的地方之前。

因为我不知道你的矩阵是如何工作的,所以让我保留一个临时 vector 和计数器来存储行。

#include <vector>
#include <iostream>
#include <cassert>

class readmatrix
{
    std::vector<int> data; //storage
    size_t rows, cols; //the counted rows and columns
    size_t col; //the counting cols in a current row

    Matrix& mtx; //refer to the matrix that has to be read
public:

    // just keep the reference to the destination
    readmatrix(Matrix& m) :data(), rows(), cols(), cols(), mtx(m)
    {}

    // make this class a istream-->istream functor and let it be usable as a stream 
    // manipulator: input >> readmatrix(yourmatrix) 
    std::istream& operator()(std::istream& s)
    {
        if(s) //if we can read
        {
            char c=0:
            s >> c; //trim spaces and get a char.
            if(c!='{') //not an open brace
            { s.setstate(s.failbit); return s; } //report the format failure
            while(s) //loop on rows (will break when the '}' will be found)
            {
                col=0;
                while(s) //loop on cols (will break when the '/' or '}' will be found)
                {
                    c=0; s >> c;
                    if(c=='/' || c=='}') //row finished?
                    { 
                        if(!cols) cols=col; //got first row length
                        else if(cols != col) //it appears rows have different length
                        { s.setstate(s.failbit); return s; } //report the format failure
                        if(c!='/') s.unget(); //push the char back for later
                        break; //row finished
                    }
                    s.unget(); //pushthe "not /" char back
                    int x; s >> x; //get an integer
                    if(!s) return s; //failed to read an integer!
                    ++col; data.push_back(x); //save the read data
                }
                ++rows; //got an entire row
                c=0; s >> c;
                if(c == '}') break; //finished the rows
                else s.unget(); //push back the char: next row begin
            }
        }
        //now, if read was successful,
        // we can dispatch the data into the final destination
        if(s)
        {        
            mtx.setsize(rows,cols); // I assume you can set the matrix size this way
            auto it = data.begin(); //will scan the inner vector
            for(size_t r=0; r<rows; ++r) for(size_t c=0; c<cols; ++c, ++it)
                mtx(r,c) = *it; //place the data
            assert(it == data.end()); //this must be true if counting have gone right
        }
        return s;
    }
};

现在你可以将矩阵读作

input >> readmatrix(matrix);

此时您会注意到代码中存在某些重复出现的模式:这在单程解析中很典型,并且可以将这些模式分组以形成子解析器。如果你一般地这样做,你 - 事实上 - 将重写 boost::spirit

当然,可以根据矩阵的工作方式(是否固定大小??)或如果行大小不匹配(部分列填充??)做什么来进行一些调整

你甚至可以添加一个格式化的输入运算符,比如

std::istream& operator>>(std::istream& s, Matrix& m)
{ return s >> readmatrix(m); }

这样你就可以做

input >> matrix;

关于c++ - C++ 中矩阵的用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27243414/

相关文章:

c++ - pthreads 进程未显示在 ps 输出中

c++ - 如何迭代无序映射的特定键的值?

php - mySQL显示为数组

java - 作为引用类型的字符串

java - "error: variable keyboard is already defined in method main(String [])"

c++ - 有没有办法禁用非常规类型的自动声明?

c++ - 文件输出8192个字符后停止

java - 我有一个对象数组,每个对象都分配了一个日期,如何按日期顺序对这些对象进行排序?

javascript - 将对象数组转换为对象到对象

javascript - `string.replace` 不改变变量