c++ - 需要帮助来完成对 k 个已排序流进行排序的功能

标签 c++ vector ostream istream

我正在完成我的作业,需要帮助来完成以下功能。我已获得以下签名:

void merge(const std::vector<istream>& inputStreams, ostream& o);

该函数应该采用 k整数流作为输入并对它们进行排序并将结果存储在 ostream 中目的。 我已经完成了函数定义,但问题是我无法通过向函数提供输入(即:istream 对象的 vector )来测试该函数。如果我尝试向函数传递一个 istream 对象的 vector ,编译器会抛出太多错误让我无法调试。 这是函数定义:

void merge( vector<istream>&  inputStreams, ostream&  o){
    vector<long long int> input_vec;
    long long int input_vec_size =  inputStreams.size();
    for(int i=0; i<input_vec_size;i++)
    {
        long long int temp;
        while(inputStreams[i]>>temp)
        {
            input_vec.push_back(temp);
        }
    }
    sort(input_vec.begin(),input_vec.end());
    for(int i=0;i<input_vec.size();i++)
    {
        o<<input_vec[i];
    }

}

并传递一个 vectoristream对象我做了以下事情:

int main()
{
    //ifstream a1,a2,a3,a4;
    filebuf fb1,fb2,fb3;
    fb1.open("fb1.txt",ios::in);
    fb2.open("fb2.txt",ios::in);
    fb3.open("fb3.txt",ios::out);
    istream a1(&fb1);
    istream a2(&fb2);
    ostream out(&fb3);
    vector<istream> inp;
    inp.push_back(a1);        
    inp.push_back(a2);
    merge(inp,out);
}

谁能帮帮我?

最佳答案

对于初学者来说,看到类型 istream 是相当不寻常的被用作对象的实际类型。原因是istream意味着用作基类,而这些基类是更经常使用的。例如,您会看到 istringstream 类型的变量或输入 ifstream比普通的旧istream更有规律.拥有一个诚实至善的变量本身并没有错 istream , 但这是不寻常的。

通常,如果你想使用一个函数来操作某种输入流,你会构造它,以便它要么接受对 istream 的引用。或指向 istream 的指针.这是处理多态类型的通用 C++ 方式。

在您的情况下,您尝试使用 vector<istream> 的事实,无论代码是否可以编译,因此都应该让您停下来思考一下您是否在做正确的事情。完全有可能,是的,你确实有一堆 istream对象,而这些对象不是 istringstream s 或 ifstream秒。但更有可能的是,您在这里的目的是说“我接受了一些输入流列表,我并不关心它们是什么类型的输入流,只要它们继承自 istream 即可。”

如果这是您希望做的,有几种方法可以解决这个问题。也许最简单的是更改 vector<istream>vector<istream *> (或者可能是 vector<shared_ptr<istream>> ,取决于上下文)。那将意味着“我想将流列表作为输入,并且由于我不能确定每个流的具体类型,我只会让客户给我每个流的指针”这将要求您对代码进行一些更改,以便在您访问 vector 的元素时,您将它们视为指针而不是真实的、诚实的istream对象。例如,行

while (inputStreams[i] >> temp) { ... }

可能需要重写为

while (*inputstreams[i] >> temp) { ... }

显式取消引用指针。

您问的另一个问题是如何测试这段代码,这是一个单独的步骤。请记住,创建 istream 类型的对象是相当不寻常的。 , 所以你可能想要制作 istringstream 类型的对象或 ifstream .下面是一个示例,说明如何创建一些流,然后将它们传递到您的函数中:

istringstream stream1("137 2718");
istringstream stream2("27 182 818");
istringstream stream3("3 14 15 92 653");

merge({ &stream1, &stream2, &stream3 }, cout);

在这里,而不是声明类型为 vector<istream *> 的局部变量,我们只是使用大括号初始化器来表示“请让我成为这些指针的 vector 。”

从您提供的示例代码来看,您似乎想要从一堆文件中读取数据。以下是您可以如何做到这一点。而不是制作 filebuf对象并将它们包装在 istream 中s,这是合法的但相当不常见,我们将只使用 ifstream :

ifstream stream1("fb1.txt");
ifstream stream2("fb2.txt");
ifstream stream3("fb3.txt");

vector<istream *> inputs;
inputs.push_back(&stream1);
inputs.push_back(&stream2);
inputs.push_back(&stream3);

merge(inputs, cout);

希望这对您有所帮助!

关于c++ - 需要帮助来完成对 k 个已排序流进行排序的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55425098/

相关文章:

c++ - 使用 gnuplot 制作 3D 曲面图

c++ - 预期类型 - 运算符函数

c++ - 如何使用另一个类的重载函数运算符(operator())?

c++ - ostream 中的困难

c++ - 混合术语

c++ - 为什么非常量 vector<bool> 元素是常量?

matlab - 如何在没有 for 循环的情况下在 matlab 中将矩阵提升为幂向量?

Python 向量的三元运算

c++ - std::vector 的 Typedef 和 ostream 运算符

c++ - 目标文件中的 ostream 运算符会发生什么?