problem:
Design a algorithm to encode a list of strings to a string. The encoded string is then sent over the network and are decoded back to the original list of strings.
Machine 1 (sender) has the function:
String encode (vector<string> STRs) { //... your code return encoded_string;}
Machine 2 (receiver) has the function:
Vector<string> decode (string s) { //... your code return strs;}
So machine 1 does:
String encoded_string = Encode (STRs);
and Machine 2 does:
Vector<string> strs2 = decode (encoded_string);
strs2
In Machine 2 should is the same as in Machine strs
1.
Implement the encode
and decode
methods.
Note:
- The string may contain any possible characters out of the valid ASCII characters. Your algorithm should is generalized enough to work on any possible characters.
- Don't use the class member/global/static variables to store states. Your encode and decode algorithms should be stateless.
- Rely on any library method such as
eval
or Serialize methods. You should implement your own Encode/decode algorithm.
Analysis:
This problem needs some skills in implementation. Once you know the tricky skill underlying it, you would think how it could is so easy!Instant Idea:can Some special characters to separate those strings. Nope! No matter what kind of special characters your use, it could appear in all individual string by chance!Then I had came up with the certain number of characters to record each string' s information in the overall string. However, how much prefix characters is enough? How to Sepearte the information forEach of the string out? that' s a headache problem!The genius idea:why not combinely use special character and size information. Wrap your string in following the encode string.encode_string=Size1:{original_string}size2:{original_string}size3:{original_string}size4:{original_string}each Original String is wrap through following way:original_string--->size1:{original_string}for a single block, how could we extract the orginal_string out of wraped string?Step1:get the start index of the block. Inital start Index is 0.-------------------------------------------------------------------intNext_start = 0; Step2:use ":" To get the orginal_string s length.-------------------------------------------------------------------intSplit_index = S.indexof (":", Next_start);intLen =integer.valueof (s.substring (Next_start, Split_index)); Step3:combinely use ":"and length information to extract the original string out.-------------------------------------------------------------------String Item= S.substring (split_index+1, split_index+1+len); Ret.add (item); Step4:update the start index forThe next string.-------------------------------------------------------------------Next_start= Split_index+1+len;
Wrong solution:
Public classCodec {//encodes a list of strings to a single string. PublicString Encode (list<string>STRs) { if(STRs = =NULL) Throw NewIllegalArgumentException ("STRs is null"); StringBuffer Buffer=NewStringBuffer (); for(String str:strs) {buffer.append (Str.length ()); Buffer.append (":"); Buffer.append (str); } returnbuffer.tostring (); } //decodes a single string to a list of strings. PublicList<string>Decode (String s) {List<String> ret =NewArraylist<string> (); intNext_start = 0; intSplit_index = S.indexof (":"); intLen =integer.valueof (s.substring (Next_start, Split_index)); while(Next_start <s.length ()) {String Item= S.substring (split_index+1, split_index+1+Len); Ret.add (item); Next_start= split_index+1+Len; Split_index= S.indexof (":", Next_start); Len=integer.valueof (s.substring (Next_start, Split_index)); } returnret; }}
MistakesAnalysis:
Last executed Input:[]mistake analysis:my first implementation are complex and so ugly!!!Since We need to DoThe same work forAll wrapped strings, we should don't allow a singly operation spill out the common block.intNext_start = 0;intSplit_index = S.indexof (":");//What if there was no string in the encoded string!!! This ugly logic incure a corner case!intLen =integer.valueof (s.substring (Next_start, Split_index)); while(Next_start <s.length ()) {String Item= S.substring (split_index+1, split_index+1+Len); Ret.add (item); Next_start= split_index+1+Len; Split_index= S.indexof (":", Next_start); Len=integer.valueof (s.substring (Next_start, Split_index));} what' s more, ' while (Next_start < s.length ()) "are great checking for cases!
Solution:
Public classCodec {//encodes a list of strings to a single string. PublicString Encode (list<string>STRs) { if(STRs = =NULL) Throw NewIllegalArgumentException ("STRs is null"); StringBuffer Buffer=NewStringBuffer (); for(String str:strs) {buffer.append (Str.length ()); Buffer.append (":"); Buffer.append (str); } returnbuffer.tostring (); } //decodes a single string to a list of strings. PublicList<string>Decode (String s) {List<String> ret =NewArraylist<string> (); intNext_start = 0; while(Next_start <s.length ()) { intSplit_index = S.indexof (":", Next_start); intLen =integer.valueof (s.substring (Next_start, Split_index)); String Item= S.substring (split_index+1, split_index+1+Len); Ret.add (item); Next_start= split_index+1+Len; } returnret; }}//Your Codec object would be instantiated and called as such://Codec Codec = new Codec ();//Codec.decode (Codec.encode (STRs));
[leetcode#271] Encode and Decode Strings