Given an input string, write a regular recursive function that returns the decoded (uncompresseed form) Run Length Encoded (is a simple form of data compression where repeated character are replaced by count followed by the character repeated) string for the input string. Below are some examples:
decode("*") =>*
decode("3+") =>+++
decode("11*") =>***********
decode("101+") =>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
decode("abcde10+10*10+10x") =>abcde++++++++++**********++++++++++xxxxxxxxxx
decode("\\") =>\
decode("\1\2\3") =>123
decode("13\7x") =>7777777777777x
decode("5\\") =>\\\\\
decode("4\12\23\3") =>111122333
decode("4\\2\3") =>\\\\33
NOTE: To represent a single backslash, it’s necessary to place double backslashes (\\) in the input string to obtain the desired input/output. For example, input string "\\1\\2\\3" is equivalent to \1\2\3.
#include<iostream> unsigned int str_to_num(char const* const str,unsigned int& pos, int const result){ if(!(*str >='0' && *str<='9')) //if not a digit return result; else{ return str_to_num(str+1,++pos, result*10+(*str-'0')); } } void fill_array(char* result,char const ch,int const repeat){ if(repeat == 0) return ; else{ *result = ch; fill_array(result+1,ch,repeat-1); } } char* decode(char const* str,int const length){ char* result = nullptr; unsigned int pos = 0; unsigned int repeat = 0; if(*str == '\0'){ result = new char[length+1]; result = result +length; //change the pointer to the end of the array *result = '\0'; return result; } if(*str>='0'&&*str<='9'){ repeat = str_to_num(str,pos,repeat); pos = *(str+pos)=='\\'?++pos:pos; //if character occurs after number increment pos to escape it str = str+pos; result = decode(str+1,length+repeat); }else{ if(*str == '\\') //skip escape character str = str+1; repeat =1; result = decode(str+1,length+1); } result = result - repeat; fill_array(result,*str,repeat); return result; } void test_decode_string(char const* str){ char* result = decode(str,0); //intially set leength to zero std::cout<<"decode("<<str<<") =>"<<result<<std::endl; delete[] result; } int main( void ){ char s0[] = "*"; char s[] = "3+"; char s3[] = "abcde10+10*10+10x"; char s1[] = "11*"; char s2[] = "101+"; char s4[] = "\\\\"; char s5[] = "\\1\\2\\3"; char s6[] = "13\\7x"; char s7[] = "5\\\\"; char s8[] = "4\\12\\23\\3"; char s9[] = "4\\\\2\\3"; test_decode_string(s0); test_decode_string(s); test_decode_string(s1); test_decode_string(s2); test_decode_string(s3); test_decode_string(s4); test_decode_string(s5); test_decode_string(s6); test_decode_string(s7); test_decode_string(s8); test_decode_string(s9); return 0; }
Given the string now do the opposite. Write a recursive function that takes a string and returns a compressed form without using any library function. For example,
encode_rle(xxxxxxxxxxx) => 11x
encode_rle(xxxxxyyyzza) => 5x3y2za1
encode_rle(abcde) => a1b1c1d1e1
encode_rle(*****@@@@@@++++++) => 5*6@6+
encode_rle(wwwwwwwwxxxyyuxaaabbboooooo88888888) => 8w3x2yu1x13a3b6o88
Below is my implementation:
#include<iostream> void fill_array(char* str, char* result){ if(*str == '\0') return ; else{ *result = *str; fill_array(str+1,result+1); } } int same_char(char const* const str){ if(*str != *(str+1)) return 1; else return 1+same_char(str+1); } char* num_to_cstr(unsigned int const i,unsigned int const length,unsigned int& pos){ char digit = '0'+i%10; char* cstr = nullptr; if(i<10){ cstr = new char[length+2]; cstr[pos] = digit; cstr[length+1]='\0'; }else{ cstr = num_to_cstr(i/10,length+1,pos); cstr[pos] = digit; } ++pos; return cstr; } char* encode_rle(char const* const str,int unsigned length =0){ char* result = nullptr; unsigned int pos = 0; unsigned int repeat = 0; if(*str == '\0'){ result = new char[length+1]; result[length] = '\0'; return result; } if(*(str+1)!='\0' && *(str) == *(str+1)){ repeat = same_char(str); ///find how many times character repeated char* int_str = num_to_cstr(repeat,0,pos); //convert it to string result = encode_rle(str+repeat,length+pos+1); fill_array(int_str,result+length); //fill the array delete[] int_str; //free memory result[length+pos] = *str; } else{ result = encode_rle(str+1,length+2); result[length+1] ='1'; result[length] = *str; } return result; }
//test function void test_encode_rle(char const* const str){ char* result = encode_rle(str); std::cout<<"encode_rle("<<str<<") => "<<result<<std::endl; delete[] result; } int main ( void ){ char s1[] = "xxxxxxxxxxx"; char s2[] = "xxxxxyyyzza"; char s3[] = "abcde"; char s4[] = "*****@@@@@@++++++"; char s5[] = "wwwwwwwwxxxyyuxaaabbboooooo88888888"; test_encode_rle(s1); test_encode_rle(s2); test_encode_rle(s3); test_encode_rle(s4); test_encode_rle(s5); return 0; }
Comments
Post a Comment