271. Encode and Decode Strings


Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is 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 be the same as strs in Machine 1.

Implement the encode and decode methods.

Note:

The string may contain any possible characters out of 256 valid ascii characters. Your algorithm should be generalized enough to work on any possible characters.
Do not use class member/global/static variables to store states. Your encode and decode algorithms should be stateless.
Do not rely on any library method such as eval or serialize methods. You should implement your own encode/decode algorithm.

方法1: size/string

思路:
grandyang: http://www.cnblogs.com/grandyang/p/5265628.html

第一种做法是把每个单词的长度储存在自己的前面并用“/”分隔开。那么在提取的时候,我们可以先拿到长度,去找对应的substr就比较方便了。

易错点

  1. iterator的使用,见comment

Complexity

Time complexity: O(n)
Space complexity: O(n)

class Codec {
public:

    // Encodes a list of strings to a single string.
    string encode(vector<string>& strs) {
        string s = "";
        for (string str: strs){
            s +=  to_string(str.size()) + "/" + str;
        }
        return s;
    }

    // Decodes a single string to a list of strings.
    vector<string> decode(string s) {
        vector<string> result;
        int i = 0;
        while(i < s.size()){
        	// find the first "/" starting from ith position,it point to it
            auto it = s.find("/", i);
            // example: 6/return, i = 0, it = 1, 提取从0开始长度为1的substr
            // example: 3/ask6/return, i = 6, it = 7, 提取从6开始长度为1的substr
            int len = stoi(s.substr(i, it - i));
            // 提取“/”之后长度为len的string
            string extract = s.substr(it + 1, len);
            result.push_back(extract);
            // 3  /  a  s  k  6  /  r  e  t  u  r  n
            // i  it          
            // 从i开始,经过len长度的string(指向上一个单词末尾),再加1(指向下一个len的开始)
            i = it + len + 1;
        }
        return result;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.decode(codec.encode(strs));

方法2: istringstream

思路:

知识点:istringstream

https://doc.bccnsoft.com/docs/cppreference_en/cppsstream/all.html
vs. istringstream/ostringstream

istringstream is for input, ostringstream for output. stringstream is input and output. You can use stringstream pretty much everywhere. However, if you give your object to another user, and it uses operator >> whereas you where waiting a write only object, you will not be happy ?

PS: nothing bad about it, just performance issues.

Complexity

Time complexity: O(n)
Space complexity: O(n)

易错点

  1. `\0` 只是一个特殊的符号,也可以用 `\n`, `\b`等待,为什么不用 `\`呢,因为test string里面包含有这个字符。
  2. 插入和提取的这两个地方都必须是单引号:插入的地方,可能仅仅对 `\0`而言不行,因为直接被string忽略了; 提取的地方,要求的分隔符是char而不是string
class Codec {
public:

    // Encodes a list of strings to a single string.
    string encode(vector<string>& strs) {
        string s = "";
        for (string str: strs){
            s +=  str + '\0';
        }
        return s;
    }

    // Decodes a single string to a list of strings.
    vector<string> decode(string s) {
        vector<string> result;
        istringstream in(s);
        string tmp;
        while (getline(in, tmp, '\0')){
            result.push_back(tmp);
        }
        return result;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值