Skip to content

Commit 5493bcd

Browse files
Hai Hoang Danggoswami-rahul
Hai Hoang Dang
authored andcommitted
Add some String solution (#359)
* Add unique morse * Add judge_circle * Add strong password * Add caesar cipher * Add contain string * Add count binary substring * Fix conflict
1 parent 37bee74 commit 5493bcd

File tree

6 files changed

+104
-1
lines changed

6 files changed

+104
-1
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ If you want to uninstall algorithms, it is as simple as:
287287
- [unique_morse](algorithms/strings/unique_morse.py)
288288
- [judge_circle](algorithms/strings/judge_circle.py)
289289
- [strong_password](algorithms/strings/strong_password.py)
290+
- [caesar_cipher](algorithms/strings/caesar_cipher.py)
291+
- [contain_string](algorithms/strings/contain_string.py)
292+
- [count_binary_substring](algorithms/strings/count_binary_substring.py)
290293
- [tree](algorithms/tree)
291294
- [bst](algorithms/tree/tree/bst)
292295
- [array2bst](algorithms/tree/bst/array2bst.py)

algorithms/strings/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@
2424
from .unique_morse import *
2525
from .judge_circle import *
2626
from .strong_password import *
27+
from .caesar_cipher import *
28+
from .contain_string import *
29+
from .count_binary_substring import *

algorithms/strings/caesar_cipher.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
"""
3+
Julius Caesar protected his confidential information by encrypting it using a cipher.
4+
Caesar's cipher shifts each letter by a number of letters. If the shift takes you
5+
past the end of the alphabet, just rotate back to the front of the alphabet.
6+
In the case of a rotation by 3, w, x, y and z would map to z, a, b and c.
7+
Original alphabet: abcdefghijklmnopqrstuvwxyz
8+
Alphabet rotated +3: defghijklmnopqrstuvwxyzabc
9+
"""
10+
def caesar_cipher(s, k):
11+
result = ""
12+
for char in s:
13+
n = ord(char)
14+
if 64 < n < 91:
15+
n = ((n - 65 + k) % 26) + 65
16+
if 96 < n < 123:
17+
n = ((n - 97 + k) % 26) + 97
18+
result = result + chr(n)
19+
return result

algorithms/strings/contain_string.py

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""
2+
Implement strStr().
3+
4+
Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
5+
6+
Example 1:
7+
Input: haystack = "hello", needle = "ll"
8+
Output: 2
9+
10+
Example 2:
11+
Input: haystack = "aaaaa", needle = "bba"
12+
Output: -1
13+
Reference: https://leetcode.com/problems/implement-strstr/description/
14+
"""
15+
def contain_string(haystack, needle):
16+
if len(needle) == 0:
17+
return 0
18+
if len(needle) > len(haystack):
19+
return -1
20+
for i in range(len(haystack)):
21+
if len(haystack) - i < len(needle):
22+
return -1
23+
if haystack[i:i+len(needle)] == needle:
24+
return i
25+
return -1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
Give a string s, count the number of non-empty (contiguous) substrings that have
3+
the same number of 0's and 1's, and all the 0's and all the 1's in these substrings are grouped consecutively.
4+
5+
Substrings that occur multiple times are counted the number of times they occur.
6+
Example 1:
7+
Input: "00110011"
8+
Output: 6
9+
Explanation: There are 6 substrings that have equal number of consecutive 1's and 0's: "0011", "01", "1100", "10", "0011", and "01".
10+
11+
Notice that some of these substrings repeat and are counted the number of times they occur.
12+
13+
Also, "00110011" is not a valid substring because all the 0's (and 1's) are not grouped together.
14+
15+
Example 2:
16+
Input: "10101"
17+
Output: 4
18+
Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's.
19+
Reference: https://leetcode.com/problems/count-binary-substrings/description/
20+
"""
21+
def count_binary_substring(s):
22+
cur = 1
23+
pre = 0
24+
count = 0
25+
for i in range(1, len(s)):
26+
if s[i] != s[i - 1]:
27+
count = count + min(pre, cur)
28+
pre = cur
29+
cur = 1
30+
else:
31+
cur = cur + 1
32+
count = count + min(pre, cur)
33+
return count

tests/test_strings.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
word_squares,
2727
convert_morse_word, unique_morse,
2828
judge_circle,
29-
strong_password
29+
strong_password,
30+
caesar_cipher,
31+
contain_string,
32+
count_binary_substring
3033
)
3134

3235
import unittest
@@ -401,5 +404,22 @@ def test_strong_password(self):
401404
self.assertEqual(3, strong_password(3,"Ab1"))
402405
self.assertEqual(1, strong_password(11,"#Algorithms"))
403406

407+
class TestCaesarCipher(unittest.TestCase):
408+
def test_caesar_cipher(self):
409+
self.assertEqual("Lipps_Asvph!", caesar_cipher("Hello_World!", 4))
410+
self.assertEqual("okffng-Qwvb", caesar_cipher("middle-Outz", 2))
411+
412+
class TestContainString(unittest.TestCase):
413+
def test_contain_string(self):
414+
self.assertEqual(-1, contain_string("mississippi", "issipi"))
415+
self.assertEqual(0, contain_string("Hello World", ""))
416+
self.assertEqual(2, contain_string("hello", "ll"))
417+
418+
class TestCountBinarySubstring(unittest.TestCase):
419+
def test_count_binary_substring(self):
420+
self.assertEqual(6, count_binary_substring("00110011"))
421+
self.assertEqual(4, count_binary_substring("10101"))
422+
self.assertEqual(3, count_binary_substring("00110"))
423+
404424
if __name__ == "__main__":
405425
unittest.main()

0 commit comments

Comments
 (0)