Написать программу, которая «сжимает» текстовый файл, считывая его и заменяя все повторяющиеся символы ххх… текстом х(n), где х - какой-либо символ, а n- количество повторений символа х. В программе так же нужно предусмотреть функцию, которая восстанавливает исходный файл из файла, «сжатого» согласно указанному алгоритму. Определить время работы алгоритма кодирования-декодирования.
Код:
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
using namespace std;
char * encode(const char *str)
{
int len = (int)strlen(str);
char * result = new char[len + 1];
memset(result, 0, len + 1);
char cnt[10];
int counter = 0;
for(int i = 0, j = 0; i < len; i++, j++)
{
result[j] = str[i];
if(str[i] == str[i+1])
{
memset(cnt, 0, 10);
strcat(result, "(");
counter = 1;
while(str[i] == str[i+1])
{
i++;
counter++;
}
sprintf(cnt, "%d", counter);
strcat(result, cnt);
strcat(result, ")");
j += strlen(cnt)+2;
}
}
return result;
}
char * repeat(char ch, int number_repeats)
{
char * result = new char[number_repeats + 1];
memset(result, 0, number_repeats + 1);
for(int i = 0; i < number_repeats; i++)
{
result[i] = ch;
}
return result;
}
int get_number_repeats(const char * str, int str_pos, int * end)
{
int result = -1;
char tmp_buf[10];
memset(tmp_buf, 0, 10);
while(isdigit(str[str_pos]))
{
sprintf(tmp_buf,"%s%c",tmp_buf, str[str_pos]);
str_pos++;
}
result = atoi(tmp_buf);
*end = str_pos;
return result;
}
char * decode(char * line)
{
int state = 0;
int len = strlen(line);
char * result = new char[512];
memset(result, 0, 512);
char tmp_buf[10];
char r_ch = 0;
for(int i = 0; i < len; i++){
if( line[i] == '(' ){
memset(tmp_buf, 0, 10);
if(i > 0)r_ch = line[i-1];
state = 1;
if(isdigit(line[i+1]))
state = 2;
}
else if( line[i] == ')' ){
if(state == 2){
char * t = repeat(r_ch, atoi(tmp_buf) -1);
strcat( result, t);
delete [] t;
state = 0;
i++;
}
}
else if( isdigit(line[i])){
if(state == 2){
state = 2;
sprintf(tmp_buf,"%s%c",tmp_buf, line[i]);
}
}
if(state == 0){
sprintf(result,"%s%c",result, line[i]);
}
else if(state == 1){
if(!isdigit(line[i]))sprintf(result,"%s%c",result, line[i]);
}
}
return result;
}
int main ()
{
string line;
char * s;
char * p;
ifstream infile ("1.txt");
ofstream outfile("out.txt", ofstream::out);
if (infile.is_open() && outfile.is_open()){
while (getline (infile,line)){
s = new char [line.length()+1];
strcpy(s, line.c_str());
s[line.length()+1] = 0;
p = encode(s);
outfile << p << endl;
delete [] s;
delete [] p;
}
infile.close();
outfile.close();
}
else cout << "Unable to open file";
infile.open("out.txt", ifstream::in);
outfile.open("restored.txt", ofstream::out);
if (infile.is_open()){
while (getline (infile,line)){
if(line.length() == 0){
outfile << endl;
continue;
}
s = new char [line.length()+1];
strcpy(s, line.c_str());
s[line.length()+1] = 0;
p = decode(s);
outfile << p << endl;
delete [] s;
delete [] p;
}
infile.close();
outfile.close();
}
else cout << "Unable to open file";
return 0;
}