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

Need help in completing a function for sorting k sorted streams

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

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

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

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 不可复制或移动,因此您不能制作 istreamvector。尝试改用 std::vector <std::istream *>(并相应地修改您的代码)。

现场演示:https://wandbox.org/permlink/20I2VQqsRI8ofaxP

对于初学者来说,istream 类型被用作对象的实际类型是很不寻常的。这样做的原因是 istream 旨在用作基础 class,而那些基础 class 是更经常使用的。例如,您会看到类型 istringstream 或类型 ifstream 的变量比普通的 istream 更常见。拥有一个诚实至善的变量本身并没有错istream,但这是不寻常的。

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

在你的例子中,你试图使用 vector<istream> 的事实,不管代码是否会编译,因此应该让你停下来想一想你是否在做正确的事情。完全有可能,是的,您确实有一堆 istream 对象,而这些对象不是 istringstreamifstream。但更有可能的是,您在这里的目的是说 "I take in some list of input streams, and I don't really care what kind of input streams they are as long as they inherit from istream."

如果这是您希望做的,有几种方法可以解决这个问题。也许最简单的方法是将 vector<istream> 更改为 vector<istream *>(或者 vector<shared_ptr<istream>>,具体取决于上下文)。这意味着 "I'd like to take as input a list of streams, and since I can't say for certain what specific type each of those streams will be, I'll just have the client give me pointers to each of them." 这将要求您对代码进行一些更改,以便在访问 vector 的元素时将它们视为指针而不是实际的、诚实的-善良 istream 个对象。例如,行

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

可能需要重写为

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

显式取消引用指针。

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

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

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

在这里,我们没有声明 vector<istream *> 类型的局部变量,而是使用大括号初始化器来表示 "please make me a vector out of these pointers."

从您提供的示例代码来看,您似乎想要从一堆文件中读取数据。以下是您可以如何做到这一点。与其制作 filebuf 对象并将它们包装在 istream 中,这是合法但相当不常见的,我们将只使用 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);

希望对您有所帮助!