Question statement
The encoded string is then decoded back to the original list of strings.
Input: ["leet","code","loveeeeeeeeeee","you"]
Output: ["leet","code","loveeeeeeeeeee","you"]
Two methods are provided with following signatures to implement
string encode(vector<string> strs) // To encode vector of strings into a single string vector<string> decode(string str) // To decode string generated by encode function to its original form and return as a vector
Solution
Here in this solution, I used N# as delimiter where N is the number of words in a letter and # is used as a delimiter.
So encoded string would look something like this after encode() method
"4#leet4#code14#loveeeeeeeeeee3#you"
n# would tell us that we need next n characters for 1 string
4# -> next 4 words after #
4# -> next 4 words after #
14# -> -> next 14 words after #
3# -> -> next 3 words after #
So during the decoding process, check for the number and # sign to split then add N number of characters into a string to get the original word and put in a vector to return original strings.
Interesting challenges emerge when trying to encode a string
1. Convert a number to string
string s = "code"; //Non encoded string int size = s.size(); // 4 - given size of a string string number =""; number += size + '0'; // 4 + 48 = 52 , and 52 is ASCII value of 4 when adding to a char '0' cout << number << endl; // output 4
ASCII value of 0 - 9 = 48 - 57.
string s = "loveeeeeeeeeee"; //Non encoded string int size = s.size(); // 4 - given size of a string string number =""; number += size + '0'; // 14+48 would return 62, which would result into > ASCII character cout << number << endl; // output >
To convert any number to string, you have to split each integer, and to do that, we must use % and / get those values.
//Converts a given number to string i.e 123 to "321" string numToString(int num){ string str = ""; if(num > 9){ while(num > 0){ int r = num % 10; // 3 | 2 | 1 str += r + '0'; // adding 3 | adding 2 | adding 1 to string num = num / 10; //12 | 1 | 0 } }else{ str += num + '0'; } return str; }
Now this does convert an integer to string correctly; however, this returns a string in reverse order since we are appending remainder of a number to string. We must convert this string in reverse to obtain the correct number.
Reverse a string
/* Follows this step for "1234" string step 1: 1 swap with 4 result : 4231 step 2: 2 swap 3 result : 4321 string size/2 - iterations. Another example: "123" - size/2 = 1 iteration step 1 - swap 1 and 3 result = "321" Done! */ //reverses string, example - 231 to 132. string reverseString(string str){ //string reversed = ""; for(int i= 0; i< str.size()/2; i++){ int index = (str.size()-1) - i ; // 2 -0, 2, 2-1 - 1 //swap char c = str[i]; str[i] = str[index]; str[index] = c; } return str; }
Decode a string
/*Example: string str = "14"; str[1] = 1; str[2] = 4; n=0 n = n*10+ (str[1] -'0') = 0+ (49-48)= 0+1 = 1 n = 1*10+ (str[2] -'0') = 10+(52-48)=10+4= 14 Done! 14 is the number. You have to multiply n with 10 to get later values. */ //Converts a given string to a number i.e "99" to 99. int strToNum(string str){ int num = 0; if(str.size() > 1){ for(auto i: str){ num = num*10 + (i - '0'); } return num; }else{ int value = (int) str[0]; value -= '0'; // minus to get to value 9... 9=57, 0=48 --> 57-48 = 9 return value; } }
Implementation of solution
//Encode string with N#String i.e 4#Ajay <- 4 (num of characters) # (delimiter) and Ajay is string. string encode(vector<string>& strs) { string str = ""; for(auto i: strs){ //str += i.size() + '0'; // This alone only works if one digit number, doesn't work for 2digits num. str += reverseString(numToString(i.size())); str += '#'; str += i; } return str; } //Decoding a given encoded string. vector<string> decode(string s){ vector<string> strs; string num; string str=""; int currentNum = 0; for(int i=0;i<s.size();i++){ if(s[i] == '#'){ currentNum = strToNum(num); num = ""; for(int j = i+1; j <= i+currentNum; j++){ str += s[j]; } strs.push_back(str); str = ""; i += currentNum; //resetting i to resume loop. }else{ num += s[i]; } } return strs; } int main() { //vector<string> strs = {"AjayVeryLongStringWithoutAnySpacesOrSpecialCharactersRepeatedManyTimesVeryLongStringWithoutAnySpacesOrSpecialCharactersRepeatedManyTimes 12#space->VeryLongStringWithoutAnySpacesOrSpecialCharactersRepeatedManyTimesVeryLongStringWithoutAnySpacesOrSpecialCharactersRepeatedManyTimesAjay"}; vector<string> strs = {"leet", "code", "loveeeeeeeeeee", "you"}; string str = encode(strs); cout << "Encoded String-> " << str << endl; vector<string> de; de = decode(str); cout << "decoded string-> "; for(auto i: de){ cout << i << " "; } //cout << reverseString("231") << endl; return 0; }
Full source code is available here : https://github.com/apprajapati9/CPlusPlus/blob/master/C%2B%2B/Leetcode/encode-decode-strings/encode-decode-%23.cpp
Another way to convert number to string
string numToString(int num){ string str = ""; int save = num; int divisor = 1; while(num > 10){ num = num / 10; divisor *= 10; } while(divisor != 1){ int right = save / divisor;// 1234/ 1000 - 1, 2, 3 save %= divisor;// 234 , 34, 4 divisor /= 10; str += right + '0'; } str += save + '0'; return str; }
The above code is following these steps which mitigate the necessity to reverse a string.
Source code here : https://github.com/apprajapati9/CPlusPlus/blob/master/C%2B%2B/Leetcode/encode-decode-strings/convert-num-to-string.cpp
Hopefully this explanation would solidify your understanding of this problem.
For any questions or suggestions, please comment and thank you.
Happy coding!
0 Comments