1-liners Ruby+Python


  • 12

    Double the pipes inside the strings, then use standalone pipes to mark string endings.

    Ruby

    def encode(strs)
      strs.map { |s| s.gsub('|', '||') + ' | ' }.join
    end
    
    def decode(s)
      s.split(' | ', -1)[0..-2].map { |s| s.gsub('||', '|') }
    end
    

    Python

    def encode(self, strs):
        return ''.join(s.replace('|', '||') + ' | ' for s in strs)
    
    def decode(self, s):
        return [t.replace('||', '|') for t in s.split(' | ')[:-1]]
    

    Python, joking

    It's forbidden, but I find it neat that Python lets me write the entire thing like that, so there :-)

    class Codec: encode, decode = repr, eval

  • 0
    M
    This post is deleted!

  • 0
    M

    good answer, you use space|space as separator, i thought it was just |


  • 0
    Y

    what if "|" occurs in some input string?


  • 0

    What about it?


  • 0
    J

    Once again, great thought! This is probably only one which doesn't need length. I have trouble making the java version working. It failed on empty string such as ("", "") as the input because split method doesn't work as expected.

    public class Codec {
    public static void main(String[] args) {
    	Codec cd = new Codec();
    	cd.decode(cd.encode(new ArrayList<String>(Arrays.asList("", ""))));
    }
    
    public String encode(List<String> strs) {
    	if (strs.isEmpty())	return null;
    	StringBuffer ans = new StringBuffer();
    	for (int i = 0; i < strs.size(); i++) {
    		ans.append(strs.get(i).replace("|", "||") + " | ");
    	}
    	return ans.toString();
    }
    
    public List<String> decode(String s) {
    	List<String> ans = new ArrayList<>();
    	if (s == null) return ans;
    	String[] strs = s.split(" \\| ");
    	if (strs.length == 0) {
    		ans.add("");
    	} else {
    		for (String ss : strs) {
    			ans.add(ss.replace("||", "|"));
    		}
    	}
    	return ans;
    }
    

    }


  • 0
    R

    if the input is:
    abc|
    abc
    then you won't be able to tell whether | is at the end of the first abc or at the beginning of the second abc when decoding


  • 0

    @rpmy But that's obviously not a string produced by encoding, so it can't be an input string for decoding.


  • 0
    R

    hey stefan, I know rpmy's meaning. what if input is {'abc', '|abc'}, or {'abc|', 'abc'}, encoding string of these two input are same: 'abc|||abc|', so how to decode it?


  • 1

    encoding string of these two input are same: 'abc|||abc|'

    No, they're encoded to this:

    {'abc', '|abc'}  =>  "abc | ||abc | "
    {'abc|', 'abc'}  =>  "abc|| | abc | "

  • 0

    @jinwu You can give split a second parameter to prevent losing empty strings, that's how I did it. Posted here now.


  • 0
    R

    ok, I see. But I still think add constant bytes to store len is more convenient


  • 0

    I have done that as well (posted here now), but while the encoding is nice, I find the decoding rather INconvenient. Takes me several lines and loop :-)


  • 0
    J

    That works, thanks!

    public class Codec {
    public static void main(String[] args) {
    	Codec cd = new Codec();
    	cd.decode(cd.encode(new ArrayList<String>(Arrays.asList("aa", "cc"))));
    }
    
    public String encode(List<String> strs) {
    	if (strs.isEmpty())	return null;
    	StringBuffer ans = new StringBuffer();
    	for (int i = 0; i < strs.size(); i++) {
    		ans.append(strs.get(i).replace("|", "||") + " | ");
    	}
    	return ans.toString();
    }
    
    public List<String> decode(String s) {
    	List<String> ans = new ArrayList<>();
    	if (s == null) return ans;
    	String[] strs = s.split(" \\| ", -1);
    	for (String ss : strs) {
    		ans.add(ss.replace("||", "|"));
    	}
    	ans.remove(ans.size() - 1);
    	return ans;
    }
    

    }


  • -1
    T

    {'a|', '|b'}
    {'a||', 'b'}
    how can you distinguish those two?


  • 0
    R

    My elegant code, although use more bytes for store len,

    class Codec {
    public:
    
        // Encodes a list of strings to a single string.
        string encode(vector<string>& strs) {
            string ans;
            for(auto e: strs){
                string tmp = to_string(e.size());
                if(tmp.size()<10){
                    string heads(10-tmp.size(), '0');
                    tmp = heads+tmp;
                }
                ans+=tmp+e;
            }
            return ans;
        }
    
        // Decodes a single string to a list of strings.
        vector<string> decode(string s) {
            int n = s.size();
            vector<string> v;
            for(int i = 0 ;i < n; ){
                int len = stoi(s.substr(i, 10));
                v.push_back(s.substr(i+10, len));
                i += 10+len;
            }
            return v;
        }
    };

  • 0
    T

    {'a|', '|b'} {'a||', 'b'} how can you distinguish those two?


  • 0
    This post is deleted!

  • 0

    @tianchengli They differ. (And their encodings differ as well, if that's what you meant).


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.