我正在学习考试,这很可能会有这样的问题:
编写一个C程序,用于处理用字符串B替换字符串A的文件,不使用临时文件或在内存中加载文件。
它实际上并不总是那样,但有点像。字符串A和B可以是任何长度(A B,或B可能取决于其他东西)。
我疯了,试图这样做!我不是要求代码,而是要求使用fseek,fgetc,fputc等组合的一些指导。这个问题很奇怪,最常见的是将整个文件加载到内存中,或者使用临时文件,我还没有在其他任何地方找到这样的东西编辑:
我允许使用posix的ftruncate
答案 0 :(得分:1)
算法:
如果B> A,你可以寻找文件的末尾,将每个字符写入下一个地方,直到你有足够的空间放置B.类似的解决方案是A> B。反过来。
他们找到A的地方是更好的解决方案。 您可以使用滚动哈希来实现此目的。 https://en.wikipedia.org/wiki/Rolling_hash
答案 1 :(得分:0)
伪伪代码。真正棘手的部分是当找到部分模式但其余部分不匹配时,如何将部分模式与当前匹配状态重新同步。代码打印图案的前导字符,然后查看剩余的部分图案如何与图案匹配。
int replace(FILE *inf, FILE *outf, const char *i_pattern, const char *o_pattern) {
const unsigned char *ip = i_pattern;
int ch;
assert(i_pattern && *i_pattern && o_pattern);
while ((ch = fgetc(inf)) != EOF) {
if (ch == *ip) {
advance ip
if (ip at \0) {
write the o_pattern, ip = i_pattern
}
continue;
}
i_len = number of matching ch in i_pattern;
if (i_len == 0) {
output ch;
continue;
}
// Now the tricky bit
print i_pattern[0];
for (i=1; i_len > 0; i++) {
if (match(&i_pattern[0], &i_pattern[i], i_len)) {
ip--
continue `while (ch...)` loop
}
print i_pattern[i];
ip--, i_len--;
}
}
print (i_pattern, length:(ip - i_pattern );
return non-zero if IO error occurred.
}
请注意,for (i=1; i_len > 0; i++) {
循环不依赖于ch
。因此,可以在启动时预先计算移位部分匹配模式的量,而不是每次重新计算。通过这项额外的工作和记忆,算法可能是O(File_length + pattern_length)
。