|
| 1 | +""" |
| 2 | +Python version 3.7.0 |
| 3 | +1.3 - URLify |
| 4 | +Write a method to replace all spaces in a string with "%20". |
| 5 | +The following only applies to C/C++: "You may assume that the string has sufficient |
| 6 | +space at the end to hold the additional characters, and that you are given the "true" length of the string" |
| 7 | +(Note: If implementing in Java, please use a character array so that you can perform this operation in place) |
| 8 | +Since we are using python, no need to use true length. I will have two functions, one with |
| 9 | +true_length and the other without. |
| 10 | +""" |
| 11 | +import unittest |
| 12 | +from typing import List |
| 13 | + |
| 14 | + |
| 15 | +def urlify(s: str) -> str: |
| 16 | + """ |
| 17 | + Given a string, this function will return a new string |
| 18 | + that replaces all of the spaces of the input string with '%20'. |
| 19 | + :param s: the original string to 'urlify' |
| 20 | + :return: string with each space from s replaced with '%20' |
| 21 | + """ |
| 22 | + buf = ['\x00'] * (len(s) * 3) |
| 23 | + for i, c in enumerate(s): |
| 24 | + buf[i] = c |
| 25 | + |
| 26 | + def _challenge(buf: List[str], original_length: int) -> None: |
| 27 | + """ |
| 28 | + Your code here. Challenge rules: |
| 29 | + * You can only reference |buf| and |original_length|, not |s|. |
| 30 | + * You can only allocate O(1) additional memory |
| 31 | + * You need to modify |buf| in-place so that the right answer is returned. |
| 32 | + * You cannot modify any part of the wrapper function. |
| 33 | + :param buf: buffer containing characters |
| 34 | + :param original_length: original length of string |
| 35 | + :return: None |
| 36 | + """ |
| 37 | + space_count = 0 |
| 38 | + for j in range(original_length): |
| 39 | + if buf[j] == ' ': |
| 40 | + space_count += 1 |
| 41 | + |
| 42 | + chars_per_space = 2 |
| 43 | + idx = original_length + space_count * chars_per_space |
| 44 | + for i in range(original_length-1, -1, -1): |
| 45 | + if buf[i] == ' ': |
| 46 | + buf[idx-1] = '0' |
| 47 | + buf[idx-2] = '2' |
| 48 | + buf[idx-3] = '%' |
| 49 | + idx -= 3 |
| 50 | + continue |
| 51 | + buf[idx-1] = buf[i] |
| 52 | + idx -= 1 |
| 53 | + _challenge(buf, len(s)) |
| 54 | + return ''.join(buf).rstrip('\x00') |
| 55 | + |
| 56 | + |
| 57 | +def urlify_no_true_length(s: str) -> str: |
| 58 | + """ |
| 59 | + This is the version of urlify without the true_length argument. |
| 60 | + Given a string and it's "true" length, this function will return a new string |
| 61 | + that replaces all of the spaces of the input string with '%20'. |
| 62 | + Note that this will return a different result than the other urlify |
| 63 | + if the other urlify's true length truncates the string with chars left over. |
| 64 | + Precondition(s): |
| 65 | + - length of s <= true_length |
| 66 | + :param s: the original string to 'urlify' |
| 67 | + :return: string with each space from s replaced with '%20' |
| 68 | + """ |
| 69 | + output = [] |
| 70 | + for c in s: |
| 71 | + if c == ' ': |
| 72 | + output.append("%20") |
| 73 | + continue |
| 74 | + output.append(c) |
| 75 | + return ''.join(output) |
| 76 | + |
| 77 | + |
| 78 | +class TestUrlifyFunction(unittest.TestCase): |
| 79 | + def test_urlify(self): |
| 80 | + cases = [ |
| 81 | + ("Mr John Smith", "Mr%20John%20Smith"), |
| 82 | + ("Miguel Hernandez", "Miguel%20Hernandez"), |
| 83 | + (" Techqueria", "%20Techqueria"), |
| 84 | + ("a b c d e f g h", "a%20b%20c%20d%20e%20f%20g%20h"), |
| 85 | + ("ihavenospaces", "ihavenospaces"), |
| 86 | + ("nospaces", "nospaces"), |
| 87 | + (" ", "%20") |
| 88 | + ] |
| 89 | + for s, expected in cases: |
| 90 | + self.assertEqual(urlify(s), expected, msg=s) |
| 91 | + |
| 92 | + def test_urlify_no_true_length(self): |
| 93 | + cases = [ |
| 94 | + ("Mr John Smith", "Mr%20John%20Smith"), |
| 95 | + ("Miguel Hernandez", "Miguel%20Hernandez"), |
| 96 | + (" Techqueria ", "%20Techqueria%20"), |
| 97 | + ("a b c d e f g h", "a%20b%20c%20d%20e%20f%20g%20h"), |
| 98 | + ("a b c d e f g h ignore this", "a%20b%20c%20d%20e%20f%20g%20h%20ignore%20this"), |
| 99 | + ("ihavenospaces", "ihavenospaces"), |
| 100 | + ("nospacesIgnoreme", "nospacesIgnoreme"), |
| 101 | + (" ", "%20") |
| 102 | + ] |
| 103 | + for s, expected in cases: |
| 104 | + self.assertEqual(urlify_no_true_length(s), expected, msg=s) |
| 105 | + |
| 106 | + |
| 107 | +if __name__ == '__main__': |
| 108 | + unittest.main() |
0 commit comments