Skip to content

Commit eaf8601

Browse files
committed
Added other methods to string manipulation.
1 parent bc5fda5 commit eaf8601

File tree

2 files changed

+132
-26
lines changed

2 files changed

+132
-26
lines changed

algorithms/string_manipulation.py

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,29 @@
11
"""
22
Some String Manipulation Algorithms
33
"""
4-
from collections import deque
4+
import string
55

66

77
class StringManipulation:
88
@staticmethod
9-
def get_number_of_vowels(string: str):
10-
if string is None:
11-
return 0
9+
def get_number_of_vowels(s: str):
1210
vowels = {'a', 'e', 'i', 'o', 'u'}
1311
counter = 0
14-
for char in string:
12+
for char in s:
1513
if char.lower() in vowels:
1614
counter += 1
1715
return counter
1816

1917
@staticmethod
20-
def reverse(string: str):
21-
if string is None:
22-
return ""
18+
def reverse(s: str):
2319
reversed_string = list()
24-
for i in range(len(string)):
25-
reversed_string.append(string[len(string) - 1 - i])
20+
for i in range(len(s)):
21+
reversed_string.append(s[len(s) - 1 - i])
2622
return "".join(reversed_string)
2723

2824
@staticmethod
29-
def reverse_word_orders(string: str):
30-
words = string.strip().split()
25+
def reverse_word_orders(s: str):
26+
words = s.strip().split()
3127
reversed_order = list()
3228
i = len(words)
3329
while i > 0:
@@ -37,8 +33,6 @@ def reverse_word_orders(string: str):
3733

3834
@staticmethod
3935
def is_rotation(s1: str, s2: str):
40-
if s1 is None or s2 is None:
41-
return False
4236
s1 = s1.strip()
4337
s2 = s2.strip()
4438
return len(s1) == len(s2) and s2 in s1 + s1
@@ -51,3 +45,67 @@ def is_rotation_2(s1: str, s2: str):
5145
if s2[i] == s1[0] and s2[i:] + s2[:i] == s1:
5246
return True
5347
return s1 == s2
48+
49+
@staticmethod
50+
def remove_duplicates(s: str):
51+
seen = set()
52+
output = list()
53+
for char in s.strip():
54+
if char not in seen:
55+
seen.add(char)
56+
output.append(char)
57+
return "".join(output)
58+
59+
@staticmethod
60+
def get_most_repeated_character(s: str):
61+
if not s:
62+
raise ValueError("The string doesn't have any characters!")
63+
char_counts = dict()
64+
most_repeated = ""
65+
max_repeat = 0
66+
for char in s:
67+
char_counts[char] = char_counts.get(char, 0) + 1
68+
if char_counts[char] > max_repeat:
69+
most_repeated = char
70+
max_repeat = char_counts[char]
71+
return most_repeated
72+
73+
@staticmethod
74+
def capitalize_first_letters(s: str):
75+
words = s.strip().split()
76+
for i in range(len(words)):
77+
first_letter = words[i][0]
78+
if first_letter in string.ascii_letters:
79+
words[i] = first_letter.upper() + words[i][1:].lower()
80+
return " ".join(words)
81+
82+
@staticmethod
83+
def is_anagram(s1: str, s2: str):
84+
if len(s1) != len(s2):
85+
return False
86+
s1 = s1.replace(" ", "").lower()
87+
s2 = s2.replace(" ", "").lower()
88+
letter_count = dict()
89+
for letter in s1:
90+
letter_count[letter] = letter_count.get(letter, 0) + 1
91+
for letter in s2:
92+
count = letter_count.get(letter, 0)
93+
if count < 1:
94+
return False
95+
letter_count[letter] = count - 1
96+
return True
97+
98+
@staticmethod
99+
def is_palindrome(s: str):
100+
i = 0
101+
j = len(s) - 1
102+
while i < j:
103+
while not s[i].isalnum() and i < j:
104+
i += 1
105+
while not s[j].isalnum() and i < j:
106+
j -= 1
107+
if s[i].lower() != s[j].lower():
108+
return False
109+
i += 1
110+
j -= 1
111+
return True

tests/test_string_manipulation.py

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,29 @@
55

66
class TestStringManipulation(TestCase):
77
def setUp(self) -> None:
8-
self.long_string = """ Hi! This is a long string for testing some algorithms of string manipulation. I have to
9-
test everything. So this text should contain multiple numbers like: 1, 2, 5. """
8+
self.long_string = """ Hi! This is a long string for testing some
9+
algorithms of string manipulation. I have to test everything. So this
10+
text should contain multiple numbers like: 1, 2, 5. """
1011
self.empty_string = ""
11-
self.one_word = "Alireza"
12+
self.one_word = "Alirezaa"
1213

1314
def test_get_number_of_vowels(self):
14-
self.assertEqual(45, StringManipulation.get_number_of_vowels(self.long_string))
15-
self.assertEqual(0, StringManipulation.get_number_of_vowels(self.empty_string))
16-
self.assertEqual(4, StringManipulation.get_number_of_vowels(self.one_word))
15+
function = StringManipulation.get_number_of_vowels
16+
self.assertEqual(45, function(self.long_string))
17+
self.assertEqual(0, function(self.empty_string))
18+
self.assertEqual(5, function(self.one_word))
1719

1820
def test_reverse(self):
19-
self.assertEqual(self.long_string[::-1], StringManipulation.reverse(self.long_string))
20-
self.assertEqual("", StringManipulation.reverse(self.empty_string))
21-
self.assertEqual(self.one_word[::-1], StringManipulation.reverse(self.one_word))
21+
function = StringManipulation.reverse
22+
self.assertEqual(self.long_string[::-1], function(self.long_string))
23+
self.assertEqual("", function(self.empty_string))
24+
self.assertEqual(self.one_word[::-1], function(self.one_word))
2225

2326
def test_reverse_word_orders(self):
24-
print(StringManipulation.reverse_word_orders(self.long_string))
25-
self.assertEqual(self.empty_string, StringManipulation.reverse_word_orders(self.empty_string))
26-
self.assertEqual(self.one_word, StringManipulation.reverse_word_orders(self.one_word))
27+
function = StringManipulation.reverse_word_orders
28+
print(function(self.long_string))
29+
self.assertEqual(self.empty_string, function(self.empty_string))
30+
self.assertEqual(self.one_word, function(self.one_word))
2731

2832
def base_test_is_rotation(self, function):
2933
self.assertTrue(function("ABCDE", "BCDEA"))
@@ -38,3 +42,47 @@ def test_is_rotation(self):
3842

3943
def test_is_rotation_2(self):
4044
self.base_test_is_rotation(StringManipulation.is_rotation_2)
45+
46+
def test_remove_duplicates(self):
47+
function = StringManipulation.remove_duplicates
48+
self.assertEqual(
49+
'Hi! Thsalongtrfem\npu.IvySxdcbk:1,25',
50+
function(self.long_string)
51+
)
52+
self.assertEqual(self.empty_string, function(self.empty_string))
53+
self.assertEqual('Alireza', function(self.one_word))
54+
55+
def test_get_most_repeated_character(self):
56+
function = StringManipulation.get_most_repeated_character
57+
self.assertEqual(" ", function(self.long_string))
58+
with self.assertRaises(ValueError) as error:
59+
function(self.empty_string)
60+
self.assertEqual(
61+
error.exception,
62+
"The string doesn't have any characters!"
63+
)
64+
self.assertEqual("a", function(self.one_word))
65+
66+
def test_capitalize_first_letters(self):
67+
function = StringManipulation.capitalize_first_letters
68+
print(function(self.long_string))
69+
self.assertEqual("", function(self.empty_string))
70+
self.assertEqual(self.one_word, function(self.one_word))
71+
72+
def test_is_anagram(self):
73+
function = StringManipulation.is_anagram
74+
self.assertTrue(function("ABCD", "BCDA"))
75+
self.assertFalse(function("ABCD", "ABCE"))
76+
self.assertTrue(function("ABCD", "ABCD"))
77+
self.assertTrue(function("", ""))
78+
self.assertFalse(function("", "B"))
79+
self.assertTrue(function("A", "A"))
80+
81+
def test_is_palindrome(self):
82+
function = StringManipulation.is_palindrome
83+
self.assertTrue(function("ABbA"))
84+
self.assertFalse(function("ABC"))
85+
self.assertTrue(function("Was it a cat I saw?"))
86+
self.assertTrue(function(""))
87+
self.assertFalse(function("Ab"))
88+
self.assertTrue(function("A!"))

0 commit comments

Comments
 (0)