diff --git a/Encode and Decode Strings/note.md b/Encode and Decode Strings/note.md new file mode 100644 index 0000000..3856928 --- /dev/null +++ b/Encode and Decode Strings/note.md @@ -0,0 +1,59 @@ +# 方法論 + +## Non ascii value + +インプットされる値はASCIIのみなので、delimeterとしてnon-ascii値を採用する方法。(ex: π, あ) + +時間計算量: o(n) +空間計算量: o(k) + +## Escaping + +エスケーピングを使用して、delimeterが元の文字列か判別がつくようにする手法。 + +- https://en.wikipedia.org/wiki/Escape_sequence + +時間計算量: o(n) +空間計算量: o(k) + +エスケープ関連 +- [double-terminated-string](https://devblogs.microsoft.com/oldnewthing/20091008-00/?p=16443) +- [Protocol Buffers](https://ja.wikipedia.org/wiki/Protocol_Buffers), [例](https://github.com/protocolbuffers/protobuf/blob/1194440c2489fc58051a245b5db74c0fd1bbf4b0/upb/json/decode.c#L356) + +## Chunked transfer encoding + +もとの文字列の長さとdelimeterを使用して、chunk毎にもとの文字列長さがわかるようencodeする方法。 + +- https://en.wikipedia.org/wiki/Chunked_transfer_encoding + +時間計算量: o(n) +空間計算量: o(k) + + +# 振り返り + +## Step1 + +値がnon-asciiであるため、non-ascii値を使用してjoin,splitを使用としたが、スペースもascii値であることに気づいておらず失敗。 + +```step1.py +class Codec: + def encode(self, strs: List[str]) -> str: + """Encodes a list of strings to a single string. + """ + return ' '.join(strs) + + def decode(self, s: str) -> List[str]: + """Decodes a single string to a list of strings. + """ + if s == '': + return [""] + else: + return s.split() + + +# Your Codec object will be instantiated and called as such: +# codec = Codec() +# codec.decode(codec.encode(strs)) +``` + diff --git a/Encode and Decode Strings/step1.py b/Encode and Decode Strings/step1.py new file mode 100644 index 0000000..3fe08d7 --- /dev/null +++ b/Encode and Decode Strings/step1.py @@ -0,0 +1,18 @@ +class Codec: + def encode(self, strs: List[str]) -> str: + """Encodes a list of strings to a single string. + """ + return ' '.join(strs) + + def decode(self, s: str) -> List[str]: + """Decodes a single string to a list of strings. + """ + if s == '': + return [""] + else: + return s.split() + + +# Your Codec object will be instantiated and called as such: +# codec = Codec() +# codec.decode(codec.encode(strs)) diff --git a/Encode and Decode Strings/step2-using-chunked-transfer-encoding.py b/Encode and Decode Strings/step2-using-chunked-transfer-encoding.py new file mode 100644 index 0000000..187d2b3 --- /dev/null +++ b/Encode and Decode Strings/step2-using-chunked-transfer-encoding.py @@ -0,0 +1,26 @@ +class Codec: + def encode(self, strs: List[str]) -> str: + """Encodes a list of strings to a single string. + """ + encoded_string = "" + + for s in strs: + encoded_string += str(len(s)) + "/:" + s + + return encoded_string + + + def decode(self, s: str) -> List[str]: + """Decodes a single string to a list of strings. + """ + decoded_strings = [] + i = 0 + + while i < len(s): + delimeter = s.find("/:", i) + word_length = int(s[i:delimeter]) + string = s[delimeter+2 : delimeter+2+word_length] + decoded_strings.append(string) + i = delimeter + 2 + word_length + + return decoded_strings diff --git a/Encode and Decode Strings/step2-using-escape.py b/Encode and Decode Strings/step2-using-escape.py new file mode 100644 index 0000000..af172f8 --- /dev/null +++ b/Encode and Decode Strings/step2-using-escape.py @@ -0,0 +1,36 @@ +class Codec: + def encode(self, strs: List[str]) -> str: + """Encodes a list of strings to a single string. + """ + res = "" + + for s in strs: + res += s.replace("/", "//") + "/:" + return res + + def decode(self, s: str) -> List[str]: + """Decodes a single string to a list of strings. + """ + res = [] + current_string = "" + + i = 0 + + while i < len(s): + if s[i:i+2] == "/:": + res.append(current_string) + current_string = "" + i += 2 + elif s[i:i+2] == "//": + current_string += "/" + i += 2 + else: + current_string += s[i] + i += 1 + + return res + + +# Your Codec object will be instantiated and called as such: +# codec = Codec() +# codec.decode(codec.encode(strs)) diff --git a/Encode and Decode Strings/step2-using-non-ascii-char.py b/Encode and Decode Strings/step2-using-non-ascii-char.py new file mode 100644 index 0000000..c730fce --- /dev/null +++ b/Encode and Decode Strings/step2-using-non-ascii-char.py @@ -0,0 +1,16 @@ +class Codec: + def encode(self, strs: List[str]) -> str: + """Encodes a list of strings to a single string. + """ + return "あ".join(strs) + + + def decode(self, s: str) -> List[str]: + """Decodes a single string to a list of strings. + """ + return s.split('あ') + + +# Your Codec object will be instantiated and called as such: +# codec = Codec() +# codec.decode(codec.encode(strs)) diff --git a/Encode and Decode Strings/step2-using-non-ascii-delimeter.cpp b/Encode and Decode Strings/step2-using-non-ascii-delimeter.cpp new file mode 100644 index 0000000..f1fdca1 --- /dev/null +++ b/Encode and Decode Strings/step2-using-non-ascii-delimeter.cpp @@ -0,0 +1,29 @@ +class Codec { +public: + + // Encodes a list of strings to a single string. + string encode(vector& strs) { + string res = ""; + for (int i = 0; i < strs.size(); i++) { + string str = strs[i]; + res += str + "あ"; + } + return res; + } + + // Decodes a single string to a list of strings. + vector decode(string s) { + vector res; + int pos = 0; + while (pos < s.size()) { + pos = s.find("あ"); + res.push_back(s.substr(0,pos)); + s.erase(0, pos+3); + } + return res; + } +}; + +// Your Codec object will be instantiated and called as such: +// Codec codec; +// codec.decode(codec.encode(strs)); diff --git a/Encode and Decode Strings/step3.py b/Encode and Decode Strings/step3.py new file mode 100644 index 0000000..3140aca --- /dev/null +++ b/Encode and Decode Strings/step3.py @@ -0,0 +1,26 @@ +class Codec: + def encode(self, strs: List[str]) -> str: + """Encodes a list of strings to a single string. + """ + encoded_string = "" + + for s in strs: + encoded_string += str(len(s)) + "#" + s + + return encoded_string + + + def decode(self, s: str) -> List[str]: + """Decodes a single string to a list of strings. + """ + decoded_strings = [] + i = 0 + + while i < len(s): + delim = s.find("#", i) + word_length = int(s[i:delim]) + decoded_str = s[delim+1 : delim + 1 + word_length] + decoded_strings.append(decoded_str) + i = delim + 1 + word_length + + return decoded_strings diff --git a/Encode and Decode Strings/step4.py b/Encode and Decode Strings/step4.py new file mode 100644 index 0000000..fbef891 --- /dev/null +++ b/Encode and Decode Strings/step4.py @@ -0,0 +1,31 @@ +class Codec: + def encode(self, strs: List[str]) -> str: + """Encodes a list of strings to a single string. + """ + encoded_string = "" + + for s in strs: + encoded_string += s.replace('/', '//') + '/:' + + return encoded_string + + def decode(self, s: str) -> List[str]: + """Decodes a single string to a list of strings. + """ + decoded_strings = [] + current_string = "" + i = 0 + + while i < len(s): + if s[i:i+2] == "/:": + decoded_strings.append(current_string) + current_string = "" + i += 2 + elif s[i:i+2] == "//": + current_string += "/" + i += 2 + else: + current_string += s[i] + i += 1 + + return decoded_strings