Skip to content

Commit a02e7a1

Browse files
authored
Added algorithm for Text Justification in Strings (TheAlgorithms#7354)
* Added algorithm for Text Justification in Strings * Added algorithm for Text Justification in Strings
1 parent 038f8a0 commit a02e7a1

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

strings/text_justification.py

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
def text_justification(word: str, max_width: int) -> list:
2+
"""
3+
Will format the string such that each line has exactly
4+
(max_width) characters and is fully (left and right) justified,
5+
and return the list of justified text.
6+
7+
example 1:
8+
string = "This is an example of text justification."
9+
max_width = 16
10+
11+
output = ['This is an',
12+
'example of text',
13+
'justification. ']
14+
15+
>>> text_justification("This is an example of text justification.", 16)
16+
['This is an', 'example of text', 'justification. ']
17+
18+
example 2:
19+
string = "Two roads diverged in a yellow wood"
20+
max_width = 16
21+
output = ['Two roads',
22+
'diverged in a',
23+
'yellow wood ']
24+
25+
>>> text_justification("Two roads diverged in a yellow wood", 16)
26+
['Two roads', 'diverged in a', 'yellow wood ']
27+
28+
Time complexity: O(m*n)
29+
Space complexity: O(m*n)
30+
"""
31+
32+
# Converting string into list of strings split by a space
33+
words = word.split()
34+
35+
def justify(line: list, width: int, max_width: int) -> str:
36+
37+
overall_spaces_count = max_width - width
38+
words_count = len(line)
39+
if len(line) == 1:
40+
# if there is only word in line
41+
# just insert overall_spaces_count for the remainder of line
42+
return line[0] + " " * overall_spaces_count
43+
else:
44+
spaces_to_insert_between_words = words_count - 1
45+
# num_spaces_between_words_list[i] : tells you to insert
46+
# num_spaces_between_words_list[i] spaces
47+
# after word on line[i]
48+
num_spaces_between_words_list = spaces_to_insert_between_words * [
49+
overall_spaces_count // spaces_to_insert_between_words
50+
]
51+
spaces_count_in_locations = (
52+
overall_spaces_count % spaces_to_insert_between_words
53+
)
54+
# distribute spaces via round robin to the left words
55+
for i in range(spaces_count_in_locations):
56+
num_spaces_between_words_list[i] += 1
57+
aligned_words_list = []
58+
for i in range(spaces_to_insert_between_words):
59+
# add the word
60+
aligned_words_list.append(line[i])
61+
# add the spaces to insert
62+
aligned_words_list.append(num_spaces_between_words_list[i] * " ")
63+
# just add the last word to the sentence
64+
aligned_words_list.append(line[-1])
65+
# join the aligned words list to form a justified line
66+
return "".join(aligned_words_list)
67+
68+
answer = []
69+
line: list[str] = []
70+
width = 0
71+
for word in words:
72+
if width + len(word) + len(line) <= max_width:
73+
# keep adding words until we can fill out max_width
74+
# width = sum of length of all words (without overall_spaces_count)
75+
# len(word) = length of current word
76+
# len(line) = number of overall_spaces_count to insert between words
77+
line.append(word)
78+
width += len(word)
79+
else:
80+
# justify the line and add it to result
81+
answer.append(justify(line, width, max_width))
82+
# reset new line and new width
83+
line, width = [word], len(word)
84+
remaining_spaces = max_width - width - len(line)
85+
answer.append(" ".join(line) + (remaining_spaces + 1) * " ")
86+
return answer
87+
88+
89+
if __name__ == "__main__":
90+
from doctest import testmod
91+
92+
testmod()

0 commit comments

Comments
 (0)