|
3 | 3 | 1.1
|
4 | 4 | Implement an algorithm to determine if a string has all unique characters.
|
5 | 5 | What if you cannot use additional data structures?
|
| 6 | +What if the input string is empty? |
| 7 | +I assume that the user will input a non-empty string |
| 8 | +If the string is empty, then raise a ValueError exception |
| 9 | +If the input is NOT a string, then raise a TypeError exception |
6 | 10 |
|
7 | 11 | Given: Expect:
|
8 | 12 | tacos true
|
|
12 | 16 | orbit true
|
13 | 17 | e true
|
14 | 18 | """
|
| 19 | +import unittest |
| 20 | + |
| 21 | + |
| 22 | +def check_is_unique_input(input_str): |
| 23 | + if not isinstance(input_str, str): |
| 24 | + raise TypeError("expected string as input") |
| 25 | + if input_str == "": |
| 26 | + raise ValueError("empty input string") |
15 | 27 |
|
16 | 28 |
|
17 | 29 | def is_unique(input_str):
|
18 |
| - freqs = {} |
| 30 | + check_is_unique_input(input_str) |
| 31 | + chars_seen = set() |
19 | 32 | for c in input_str:
|
20 |
| - if c not in freqs: |
21 |
| - freqs[c] = 1 |
22 |
| - else: |
| 33 | + if c in chars_seen: |
23 | 34 | return False
|
| 35 | + chars_seen.add(c) |
24 | 36 | return True
|
25 | 37 |
|
26 | 38 |
|
27 | 39 | def is_unique_no_additional_data_structures(input_str):
|
28 |
| - for i in range(0, len(input_str)): |
29 |
| - for j in range(i+1, len(input_str)): |
30 |
| - if input_str[i] == input_str[j]: |
31 |
| - return False |
| 40 | + check_is_unique_input(input_str) |
| 41 | + for i, c in enumerate(input_str): |
| 42 | + if c in input_str[i+1:]: |
| 43 | + return False |
32 | 44 | return True
|
33 | 45 |
|
34 | 46 |
|
35 |
| -def main(): |
36 |
| - test1 = "tacos" |
37 |
| - test2 = "swag" |
38 |
| - test3 = "bobby" |
39 |
| - test4 = "california" |
40 |
| - test5 = "orbit" |
41 |
| - test6 = "e" |
42 |
| - |
43 |
| - # run tests, want to get all 'True' in the console output |
44 |
| - print(is_unique(test1) == True) |
45 |
| - print(is_unique(test2) == True) |
46 |
| - print(is_unique(test3) == False) |
47 |
| - print(is_unique(test4) == False) |
48 |
| - print(is_unique(test5) == True) |
49 |
| - print(is_unique(test6) == True) |
| 47 | +class TestIsUniqueFunction(unittest.TestCase): |
| 48 | + def test_is_unique(self): |
| 49 | + self.assertFalse(is_unique("techqueria")) |
| 50 | + self.assertTrue(is_unique("tacos")) |
| 51 | + self.assertTrue(is_unique("swag")) |
| 52 | + self.assertFalse(is_unique("bobby")) |
| 53 | + self.assertFalse(is_unique("california")) |
| 54 | + self.assertTrue(is_unique("orbit")) |
| 55 | + self.assertTrue(is_unique("e")) |
| 56 | + with self.assertRaises(TypeError): |
| 57 | + is_unique(8) |
| 58 | + with self.assertRaises(ValueError): |
| 59 | + is_unique("") |
50 | 60 |
|
51 |
| - print(is_unique_no_additional_data_structures(test1) == True) |
52 |
| - print(is_unique_no_additional_data_structures(test2) == True) |
53 |
| - print(is_unique_no_additional_data_structures(test3) == False) |
54 |
| - print(is_unique_no_additional_data_structures(test4) == False) |
55 |
| - print(is_unique_no_additional_data_structures(test5) == True) |
56 |
| - print(is_unique_no_additional_data_structures(test6) == True) |
| 61 | + def test_is_unique_no_additional_data_structures(self): |
| 62 | + self.assertFalse(is_unique_no_additional_data_structures("techqueria")) |
| 63 | + self.assertTrue(is_unique_no_additional_data_structures("tacos")) |
| 64 | + self.assertTrue(is_unique_no_additional_data_structures("swag")) |
| 65 | + self.assertFalse(is_unique_no_additional_data_structures("bobby")) |
| 66 | + self.assertFalse(is_unique_no_additional_data_structures("california")) |
| 67 | + self.assertTrue(is_unique_no_additional_data_structures("orbit")) |
| 68 | + self.assertTrue(is_unique_no_additional_data_structures("e")) |
| 69 | + with self.assertRaises(TypeError): |
| 70 | + is_unique_no_additional_data_structures(8) |
| 71 | + with self.assertRaises(ValueError): |
| 72 | + is_unique_no_additional_data_structures("") |
57 | 73 |
|
58 | 74 |
|
59 | 75 | if __name__ == '__main__':
|
60 |
| - main() |
| 76 | + unittest.main() |
0 commit comments