Problem
Given an array of characters, replace all occurrences of a space with another string. Assume that the array has enough space to contain all of the replacements.
Input
A
- An array of characters which may or may not have spacesword
- The string to replace spaces with.
Approach
The brute force solution for this problem is to allocate a new array \(B\), and add each non-space character occurrence in A
into \(B\). If we do encounter a space character, we simply add all characters in word
into \(B\), and then proceed with the iteration of the rest of the characters in A
.
Optimization
The above approach is most likely not efficient enough, as allocating a new array can be costly in space.
Instead, the better way is to count the number of spaces, and determine where the last character will be in the final array, after the replacements are inserted. We can set this index pointer to \(p_{final}\).
Then, find the last non-null character in A
, which is the original size of the string in A
(we do not want to include the empty null characters in A
). We can set this index pointer to \(p{last}\). Once we find these two sizes, we can then copy the character at \(p{last}\) into \(p{final}\), and decrement both \(p{last}\) and \(p{final}\). When \(p{last}\) is a space character, we add the word
string character-by-character at \(p_{final}\), before resuming the former logic.
Solution
# assumes that A has enough space to contain the words
def replace_all(A, word):
# count blanks
blanks = 0
size = 0
for i, c in enumerate(A):
if c == ' ':
blanks += 1
elif c is None:
break
size += 1
last_char_ptr = size
final_char_ptr = final_size = size + ((len(word) - 1) * blanks)
while last_char_ptr > 0:
if A[last_char_ptr] != ' ':
A[final_char_ptr] = A[last_char_ptr]
final_char_ptr -= 1
else:
ctr = len(word) - 1
while ctr >= 0:
A[final_char_ptr] = word[ctr]
ctr -= 1
final_char_ptr -= 1
last_char_ptr -= 1
return "".join(A[:final_size])