我有两个文本文件,每个文件都有从最低到最高排序的未知数量的整数...例如:
输入文件1:1 3 5 7 9 11 ...
输入文件2:2 4 6 8 10 ....
我想从两个文件中获取这些数字,从低到高排序,然后将输入文件中的已排序数字的完整列表输出到单个输出文件。我到目前为止......
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "iosort.h"
int main()
{
const char* filename1 = "numberlist1.txt";
const char* filename2 = "numberlist2.txt";
std::ofstream ofs("output.txt");
std::ifstream ifs1, ifs2;
std::string input1, input2;
ifs1.open(filename1);
std::getline(ifs1, input1);
std::cout << "Contents of file 1: " << input1 << std::endl;
ifs2.open(filename2);
std::getline(ifs2, input2);
std::cout << "Contents of file 2: " << input2 << std::endl;
ioSort(ifs1, ifs2, ofs);
return 0;
}
和我的功能......
#include <fstream>
#include <sstream>
#include <vector>
#include "iosort.h"
void ioSort(std::ifstream& in1, std::ifstream& in2, std::ofstream& out)
{
int a, b;
std::vector<int> f1, f2, f3; //create one vector for each input stream
while (in1 >> a)
{
f1.push_back(a);
}
while (in2 >> b)
{
f2.push_back(b);
}
//now f1 and f2 are vectors that have the numbers from the input files
//we know that in these input files numbers are sorted from low to high
if (f1.size() > f2.size()) //input stream 1 was larger
{
for (int i = 0; i < f2.size(); i++)
{
if (f1[i] > f2[i]) //number at input vector 2 less that respective pos
{ //in input vector 1
f3.push_back(f2[i]);
}
else if(f1[i] == f2[i]) //numbers are equal
{
f3.push_back(f1[i]);
f3.push_back(f2[i]);
}
else //number in 1 is less than that in vector 2
{
f3.push_back(f1[i]);
}
}
for (int i = f2.size(); i < f1.size(); i++)
{
f3.push_back(f1[i]); //push remaining numbers from stream 1 into vector
}
}
else //input stream 2 was larger
{
for (int i = 0; i < f1.size(); i++)
{
if (f1[i] > f2[i]) //number at input vector 2 less that respective pos
{ //in input vector 1
f3.push_back(f2[i]);
}
else if(f1[i] == f2[i]) //numbers are equal
{
f3.push_back(f1[i]);
f3.push_back(f2[i]);
}
else //number in 1 is less than that in vector 2
{
f3.push_back(f1[i]);
}
}
for (int i = f1.size(); i < f2.size(); i++)
{
f3.push_back(f1[i]); //push remaining numbers from stream 2 into vector
}
}
//send vector contents to output file
for (int i = 0; i < f3.size(); i++)
{
out << f3[i] << " ";
}
}
每次编译和运行时,都会创建文件output.txt,但它是空的。任何人都可以指出我做错了什么。如果,在主要方面,我做了类似的事情:
out << 8 << " " << 9 << std::endl;
然后它将显示在输出文件中。
答案 0 :(得分:1)
AHA!发现你的错误。您打开文件,然后直接将其读取到stdout(列出文件内容的位置),然后将相同的流传递给您的函数。你不能做这个。无论何时从文件中读取,流都会进一步移动到文件中。当你进入排序功能时,你就在文件的末尾,所以没有数字被读取!
您需要删除
行std::getline(ifs1, input1);
std::cout << "Contents of file 1: " << input1 << std::endl;
和
std::getline(ifs2, input2);
std::cout << "Contents of file 2: " << input2 << std::endl;
相反,在将它们存储在矢量中之后将它们打印出来。
我将把剩下的回复留在下面,因为你或后代可能需要它。
我不确定输出文件问题是怎么回事。浏览整个链条,看看它失败的地方:
您确实遇到其他问题,您的合并功能有错误。您最终会跳过某些元素,因为您只对两个数组使用一个索引。考虑一下:您只需将一个数字推入f1[i] > f2[i]
或f1[i] < f2[i]
的输出数组中,但您可以通过递增i
来放弃这两个数字。
您可以采取合并循环并进行大量简化,同时修复错误:)。
auto it = f1.cbegin();
auto jt = f2.cbegin();
while (it != f1.cend() && jt != f2.cend()) {
if (*it < *jt) f3.push_back(*jt++); //f2 was bigger, push f2>f3 and increment f2 index
else if (*it > *jt) f3.push_back(*it++); //f1 was bigger, push f1>f3 and increment f1 index
else { //implicit equals, only option left
f3.push_back(*jt++);
f3.push_back(*it++);
}
}
while (it != f1.cend()) f3.push_back(*it++);
while (jt != f2.cend()) f3.push_back(*jt++);
所以现在f3包含你的排序数组,按O(m + n)时间排序。如果您是为了学习而这样做的话,我会先尝试使用您的方法来解决您的错误,然后再切换到此。
如果你想编写更少的代码并且速度不是问题,你也可以使用<algorithm>
来做这件事,但这是一个糟糕的O((n + m)lg(n + m))
auto it = f1.cbegin();
auto jt = f2.cbegin();
while (it != f1.cend()) f3.push_back(*it++);
while (jt != f2.cend()) f3.push_back(*jt++);
std::sort(f3.begin(), f3.end());
答案 1 :(得分:1)
为了做空:
#include <fstream>
#include <algorithm>
#include <iterator>
int main()
{
std::ifstream infile1("infile1.txt");
std::ifstream infile2("infile2.txt");
std::ofstream outfile("outfile.txt");
std::merge(
std::istream_iterator<int>{infile1}, std::istream_iterator<int>{},
std::istream_iterator<int>{infile2}, std::istream_iterator<int>{},
std::ostream_iterator<int>{outfile, " "}
);
}
std::merge
是一种STL算法,它将两个已排序的范围合并为一个已排序的范围。范围是这种情况的文件。使用std::istream_iterator<int>
将文件视为范围。输出文件使用std::ostream_iterator<int>
作为范围进行访问。
答案 2 :(得分:1)
由于您在致电std::getline()
之前使用ioSort()
正在阅读该文件,因此无需读取排序功能。
您可以使用seekg()
回退到文件的开头。
ifs1.clear();
ifs1.seekg(0, ifs1.beg);
ifs2.clear();
ifs2.seekg(0, ifs1.beg);
ioSort(ifs1, ifs2, ofs);