需要帮助完成排序k个排序流的功能

问题描述 投票:0回答:2

我正在完成我的任务,需要帮助完成以下功能。我收到了以下签名:

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);
}

谁能帮我?

c++ vector ostream istream
2个回答
3
投票

对于初学者来说,将istream类型用作对象的实际类型是相当不寻常的。这样做的原因是istream用作基类,而那些基类是更经常使用的。例如,你会看到istringstream类型的变量或类型ifstream,而不仅仅是普通的旧istream。本身并没有错误的变量是一个诚实的善良istream,但这是不寻常的。

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

在你的情况下,你试图使用vector<istream>的事实,无论代码是否编译,都应该让你暂停一下,思考你是否做了正确的事情。完全有可能,是的,你确实有一堆istream对象,而那些对象不是istringstreams或ifstreams。但更可能的是,你在这里想要做的是说“我接受了一些输入流列表,我并不关心它们是什么样的输入流,只要它们继承自istream。”

如果这是你希望做的,有几种方法可以解决这个问题。也许最简单的方法是将vector<istream>改为vector<istream *>(或者可能是vector<shared_ptr<istream>>,视情况而定)。这意味着“我想把输入的流列表作为输入,因为我不能确定每个流的具体类型是什么,我只是让客户给我指向每个流的指针“。这将要求您对代码进行一些更改,以便在访问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 *>类型的局部变量。

从您提供的示例代码看起来,您希望从一堆文件中读取数据。这是你如何做到这一点。而不是制作filebuf对象并将它们包装在istreams中,这是合法但相当罕见的,我们将只使用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);

希望这可以帮助!


1
投票

istream不可复制或移动,因此你不能制作vectoristream。请尝试使用std::vector <std::istream *>(并相应地修改您的代码)。

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

© www.soinside.com 2019 - 2024. All rights reserved.