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

时间:2019-03-29 20:32:05

标签: c++ vector ostream istream

我正在做作业,需要帮助来完成以下功能。已为我提供以下签名:

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

}

为了传递vector个对象中的一个istream,我执行了以下操作:

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

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

对于初学者来说,看到类型istream被用作对象的实际类型是很不寻常的。这样做的原因是istream被用作基类,而那些基类是更经常使用的基类。例如,您将看到类型istringstream或类型ifstream的变量比普通的旧istream更规则。从本质上讲,拥有一个诚实善良的istream变量并没有错,但这是不寻常的。

通常,如果您想使用操纵某种输入流的函数,则可以对其进行结构化,以使其接受对istream的引用或对{{1}的指针}。这是处理多态类型的通用C ++方法。

在您的情况下,无论代码是否会编译,您都在尝试使用istream的事实,因此应该让您稍稍思考一下您是否做对了事情。是的,您确实确实确实有一堆vector<istream>对象,而这些对象不是istreamistringstream s。但是更有可能的是,您打算在这里做的是说“我接受了一些输入流,并且只要它们继承自ifstream,我就不在乎它们是什么样的输入流。”

如果您希望这样做,可以使用多种方法来解决。也许最简单的方法是将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对象并将它们包装在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);

希望这会有所帮助!

答案 1 :(得分:1)

tor是不可复制或不可移动的,因此您不能在istream中创建vector。尝试改用istream(并相应地修改代码)。

实时演示:https://wandbox.org/permlink/20I2VQqsRI8ofaxP