在不使用数组的情况下对二进制文件中的数据进行排序
Sorting data in binary file without using arrays
你好,我有一个作业,我应该生成随机数。然后将它们写入二进制文件。之后,我应该读取数据将其打印到屏幕上。最后,我必须对数据和输出进行排序。我必须在不使用数组的情况下执行此操作。我能够完成前两个部分。但是,我无法正确完成最后一部分,所以我去了谷歌和YouTube寻找有关如何做到这一点的插图,但我不走运。我真的很想知道我做错了什么,谢谢。
我想我应该使用递归 fseek 和强制转换来避免使用数组;但是,我不知道如何使用它们。
这是我的代码以及输出:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
using namespace std;
//Function prototypes
void Write_File(int num);
void Read_File(int num);
void Compare(int num);
//**********************
int main()
{
int num = 0;
cout << "Enter a positive number to generate random numbers ";
cin >> num;
Write_File(num);
Read_File(num);
Compare(num);
return 0;
}
//***************
// Functions Definitions
void Write_File(int num)
{
ofstream fout("sortfile.dat", ios::out | ios::binary | ios::beg);
int number = 0;
if (fout.is_open())
{
for (int x = 0; x < num; x++)
{
number = rand();
fout << number << endl;
}
fout.close();
}
else
{
cout << "Error, File not opened" << endl;
}
}
void Read_File(int num)
{
ifstream fin("sortfile.dat", ios::in | ios::binary | ios::beg);
int number = 0;
cout << endl << "randomly generated numbers befor sortingn";
if (fin.is_open())//check first if open already
{
for (int i = 0; i < num; i++)
{
fin >> number;
cout << number << endl;
}
fin.close();
}
else
cout << "File not opened in read phase." << endl;
}
void Compare(int num)
{
int number = 0;
int temp = 0;
int hold = 0;
ifstream fin("sortfile.dat", ios::in | ios::binary | ios::beg);
if (fin.is_open())//check first if open already
{
for (int i = 0; i < num; i++)
{
fin >> number;
fin >> temp;
if (number > temp)
{
hold = temp;
temp = number;
number = hold;
}
else
{
ofstream fout("sortfile.dat", ios::out | ios::binary | ios::beg);
fout << number;
fout << temp;
}
ofstream fout("sortfile.dat", ios::out | ios::binary | ios::beg);
fout << number;
fout << temp;
}
cout << endl << "Nums after sortn";
for (int i = 0; i < num; i++)
{
fin >> number;
cout << number << endl;
}
fin.close();
}
else
cout << "File not opened in read phase." << endl;
}
输出:
Enter a positive number to generate random numbers 4 randomly generated numbers befor sorting 41 18467 6334 26500 Nums after sort 6334 6334 6334 6334 Press any key to continue . . .
好的,这里有几点问题。 首先,您将无法仅通过交换相邻元素来进行一次性排序。 那将是一个O(n(排序,如果你设法实现它,你将立即成为一个计算机科学名人。 你的教授说你不能使用数组? 如果"数组"是指任何类型的内存缓冲区,那只是愚蠢的。如果你想要一个不使用数组的排序,从字面上看,只需使用 std::map。 从文件中读取数字时,将数字插入到地图中。 然后,使用迭代器按排序顺序检索数字,并在执行此操作时打印出它们。
其次,您正在使用文件 io 做一些可能不是您想要的事情。 在从文件中读取数字对然后可能交换它们的循环中,控制流允许将数字对写入文件两次,如果它们按排序顺序排列。 此外,您可以在每个循环迭代中构造一个或两个 ofstream 对象。 每个新的输出流都从文件的开头开始,因此您重复写入文件的开头。 在打印出"排序"内容之前,您也不会将输入流查找到文件开头。它打印出相同数字 4 次的原因是它已到达文件的末尾,并且没有为"数字"分配任何新值。
我的建议是真正避免尝试同时读取和写入文件。 读取数字(不是数组,请注意;)(,对它们进行排序,然后输出它们。(从赋值规范来看,您似乎不必再次将它们写入文件,但我不确定(。
据我所知,请继续重新创建输出流,这意味着您继续写入文件的开头。
在您的比较函数中:
for (int i = 0; i < num; i++)
{
...
// for every iteration you create an output stream at the beginning of the file
ofstream fout("sortfile.dat", ios::out | ios::binary | ios::beg);
fout << number;
fout << temp;
}
嗯,要对一堆元素进行排序,无论您使用哪种算法,都会有一段时间您至少必须将一个元素(或其索引(存储在其存储中的指定位置 =>普通程序员使用数组(或数组或索引(所称呼的。
您的要求可以通过两种方式理解:
- 您不能使用数组,但可以使用其他C++容器。好吧,取一个向量(填充后像数组一样使用(,或者按照@c_dubs的建议使用地图。也许吧,但是如果我要求不使用数组并且不明确允许C++容器,我不会对该解决方案感到满意
- 您根本无法在内存存储中使用。您必须直接对磁盘上的文件(或文件的副本(进行排序。如果您遵循该路径,只需使用 fseek 在文件上移动指针,您就可以直接在磁盘上定义的位置读取和写入元素。这足以使用任何类型的算法。
当心:我的建议是对该分配使用直接磁盘排序,但在现实世界中永远不要这样做!无论如何,在对大量元素进行排序时,将初始数据分成足够小的束以在内存中处理,对它们进行排序并将它们存储回磁盘,然后合并这些排序的文件,这很有用。这是对无法加载到内存中的数据进行排序的唯一万无一失的方法。
我的猜测是,您可以使用变量来保存文件中的数字,并使用多个文件来保存临时数据(或您随机访问的单个文件,就好像它是 4 个文件一样(。您可以使用 4 个文件实现自下而上的 2 路合并排序。它类似于 wiki 文章中提到的 4 磁带驱动器排序。
http://en.wikipedia.org/wiki/Merge_sort#Use_with_tape_drives
- 如何对点云数据进行排序
- 如何使用 QSortFilterProxyModel::sort 对 Qlist 中的数据进行排序
- 保持排序的数据结构,允许log N插入时间,并且可以返回我在log N中查找的元素的索引
- 使用选择排序对数组数据结构进行排序,但它不起作用
- 为什么我的代码没有对数组中第二个索引上的数据进行排序?
- 使用 QSortFilterProxyModel 对 Qml ListView 的数据进行排序
- 读取 C++ 中的 txt 数据,展开为行或列并排序
- C++ 从文件中获取数据时使用 strcpy 和 strcmp 按字母顺序对数组进行排序?
- 存储在 std::map/std::set 中,与在存储所有数据后对向量进行排序
- 尝试创建排序的动态列表(数据结构)
- 固定大小的容器,其中元素被排序,并可以为C 中的数据提供原始指针
- 排序算法,使用模板按内部数据对对象进行排序
- 对多个数据成员进行排序
- 递归定义数组中的数据对齐和排序
- 如何修复输出显示,以便显示正确排序的数据
- 为什么我的气泡排序不适用于双精度数据类型?
- 气泡排序不传递数据或不起作用
- 使用 stl::map 和 stl::unordered_map 对包含大量重复元素的数组数据进行排序
- 数据排序依据是哪一列,QTableWidget
- 寻找更好的数据排序方法