题目:
某工业监控设备不断发回采样数据。每个数据是一个整数(0到1000之间)。各个数据间用空白字符(空格,TAB或回车换行)分隔。这些数据以文本形式被存储在文件中。
因为大多数时候,相邻的采样间隔数据是相同的,可以利用这个特征做数据的压缩存储。其方法是:对n(n>1)个连续相同的数字只记录n和该数字本身;对m(m>0)个连续不重复的数字,则记录
m*-1 和这些数字本身(之所以用负数,是为了与第一种情况区分,便于解压缩)。 例如:采样数字: 12 34 34 25 25 25 25
11 15 17 28 14 22 22 22 13 则根据上述规则变化后:
-1 12 2 34 4 25 -5 11 15 17 28 14 3 22 -1 13 下面的程序实现了这个功能。请仔细阅读分析代码,填写空白的部分。
#include<bits/stdc++.h> using namespace std; const int BUF_N = 1024; void pop(int s, int* buf, int c, FILE* fp) { int i; if(s) //数字相同的情况 { fprintf(fp, "%d %d ", c, *buf); } else//数字不同 { fprintf(fp, "%d ", -c); for(i=0; i<c; i++) { fprintf(fp, "%d ", buf[i]); } } } void dopack(FILE* r, FILE* w) { int buf[BUF_N]; int pos = 0; // 下一个数字在buf中将要存放的位置 数字相同时 占用一个位置 int c = 0; // 当前段已读入的整数个数 int pst; //标记数字是否相同 int cst; while(fscanf(r, "%d", buf+pos)==1) { if(c==0)//开始读入 { c = pos = 1; continue; } if(c==1) { pst = buf[0] == buf[1];//判断读入的第二个字符 是否和第一个相同 相同则为1 下面的pos不加 否则pos移动到下一位置 pos = pos + 1 - pst; c = 2; continue; } cst = buf[pos-1] == buf[pos];//判断任意前后相邻的两个数是否相同 if(pst && !cst)// 之前数相同 发现后面的数不相同 { pop(pst, buf, c, w); buf[0] = buf[1]; c = pos = 1; pst = cst; } else if(!pst && cst || pos == BUF_N-1)//达到文件最大位置 或者 不相同的数 遇到了相同的数 { pop(pst, buf, c-1, w); //把pos-1之前的放入文件 buf[0] = buf[pos-1]; c = 2; if(!cst)//到了最大内存处 { buf[1] = buf[pos]; pos = 2; } else//遇到相同的数 { pos = 1; pst = cst; //置为 1 //pst = ______________; // 填空1 } } else //既相同 又连续 或者 既不相同 也不连续 { c++; if(!pst) pos++;//对应情况2 } } // while if(c > 0){//到了最后字符 发现 相同且连续的 pop(pst, buf, c, w); } //if(c>0) _____________________________; // 填空2 } int main() { FILE* rfp; FILE* wfp; if((rfp=fopen("input.txt", "r")) == NULL) { printf("can not open %s!\n", "input.txt"); exit(1); } if((wfp=fopen("output.txt", "w")) == NULL) { printf("can not open %s!\n", "output.txt"); fclose(rfp); exit(2); } dopack(rfp, wfp); fclose(wfp); fclose(rfp); }