我被要求使用shell排序对文件进行排序(并快速排序,但我认为如果我找到了一种方法,我将能够做到这两种方式)。我一直在想什么可能会有所帮助,但我找不到办法。我有一个数组的算法,但我想不出办法让它与文件一起工作。
有什么办法可以做到吗?
编辑:
在AndréPuel发布的代码的帮助下,我能够编写一些目前正在运行的代码,如果你想查看它就是这样:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
#include <sstream>
using namespace std;
int toNum(const string &s) {
stringstream ss(s);
int n;
ss >> n;
return n;
}
string toStr(int n) {
stringstream ss;
ss << n;
string s;
ss >> s;
return string(5 - s.size(),' ') + s;
}
int getNum(fstream &f,int pos) {
f.seekg(pos*5);
string s;
for(int i = 0; i < 5; ++i) s += f.get();
return toNum(s);
}
void putNum(fstream &f, int pos,int n) {
f.seekp(pos*5);
f.write(toStr(n).c_str(),5);
}
int main() {
fstream input("entrada1",fstream::in | fstream::out);
string aux;
getline(input,aux);
int n = aux.size() / 5,temp,j;
int gaps[] = {701,301,132,57,23,10,4,1};
int g = sizeof(gaps)/sizeof(gaps[0]);
for(int k = 0; k < g; ++k) {
for(int i = k; i < n; ++i) {
temp = getNum(input,i);
for(j = i; j >= k and getNum(input,j - k) > temp; j -= k) {
putNum(input,j,getNum(input,j - k));
}
putNum(input,j,temp);
}
}
input.close();
return 0;
}
答案 0 :(得分:3)
当您在C ++中打开文件时,您有两个指针。 getter指针和putter指针。它们表明您正在撰写和阅读文件的位置。
使用seekp,您可以告诉您要写的位置。使用tellp,您知道要写的位置。每当你写东西时,推杆指针就会自动前进。
使用这些操作可以轻松模拟数组。让我给你看一些代码:
class FileArray {
public:
FileArray(const char* path)
: file(path, std::fstream::app|std::fstream::binary)
{
file.seekg(0,std::fstream::end);
size = file.tellg();
}
void write(unsigned pos, char data) {
assert(pos < size );
file.tellp(pos);
file.put(data);
}
char read(unsigned pos) {
assert(pos < size);
file.seekg(pos);
return file.get();
}
private:
std::fstream file;
std::size_t size;
}
这是一种处理文件的天真方式,因为您假设随机访问。那么,随机访问是正确的,但它可能很慢。当您访问彼此靠近的数据(空间位置)时,文件流的工作速度会更快。
尽管如此,这是一个很好的方式来开始处理你的问题,你有经验的文件IO,你将找到方法来提高你的具体问题的性能。让我们保持婴儿的步伐。
我想让你注意的另一件事是,当你执行写操作时,数据会被重定向到将写入文件的fstream。我知道内核会尝试缓存这些东西,并优化速度,但如果你有某种缓存层以避免直接写入磁盘,那么仍然会更好。
最后,我认为你正在处理字符(因为它会更容易),但你可以处理其他数据类型,你只需要注意索引和数据类型的大小。例如,long long
类型的大小为8个字节,如果要访问文件数组中的第一个元素,则将访问位置8 * 0,您将不得不读8个字节。如果你想要第10个元素,你将访问位置8 * 10并再次读取8个字节的数据来构造long long
值。