寫在開頭的話:
當想寫這個的時候,發現已經有人做了這個工作了,詳情請見Python基礎算法/劍指offer,然而依然決定自己寫下這個系列,作爲算法部分的鞏固和提高。在自己寫完後會借鑑Python基礎算法/劍指offer的代碼,如有部分重複,還請見諒。
開始想到list的append的函數是O(1)的複雜度(見Python各種內置結構的複雜度),就想到新建一列表,碰到空格就append “%” “2” “0"三個字符就完事了,詳情見代碼:
# -*- coding: UTF-8 -*-.
'''
請實現一個函數,將一個字符串中的空格替換成“%20”。
例如,當字符串爲We Are Happy.則經過替換之後的字符串爲We%20Are%20Happy。
'''
def solve(string):
'Function to solve problem.'
if not isinstance(string, str):
print "invalid string"
return
string = list(string)
stringReplace = []
for item in string:
if item == ' ':
stringReplace.append('%')
stringReplace.append('2')
stringReplace.append('0')
else:
stringReplace.append(item)
print "".join(stringReplace)
def test():
'Test the program.'
string = "hello world"
solve(string)# "hello%20world"
string = " helloworld"
solve(string)# "%20helloworld"
string = 1
solve(string)# "invalid string"
string = None
solve(string)# "invalid string"
# def input():
# 'Input by hand'
# # 輸入單個數字
# x = int(raw_input())
# # 輸入兩個數字
# [n, m] = map(int, raw_input().strip().split(' '))
# # 輸入一串數字
# a = map(int, raw_input().strip().split(' '))
# # 輸入字符串
# b = list(raw_input())
# solve(x, n, m, a, b)
if __name__ == "__main__":
#input()
import time
previousTime = time.time()
test()
nowTime = time.time()
print "using %f second." % (nowTime - previousTime)
結果爲:
hello%20world
%20helloworld
invalid string
invalid string
using 0.000068 second.
想到Python的內存分配(見Python中list的實現),可知Python中list的內存是動態分配的,每次新分配的list雖然會留預留空間,這樣不用每次append的時候都重新分配內存一次,而每次動態分配的時候是不需要內存起始位置不會變,可見以下代碼:
>>> a = []
>>> a.__sizeof__()
40
>>> id(a)
140025737918008
>>> a.append('a')
>>> a.__sizeof__()
72
>>> id(a)
140025737918008
所以是O(n)的時間效率加上重新分配內存的效率。
下面是與書本上的例子相同的代碼:
# -*- coding: UTF-8 -*-.
'''
請實現一個函數,將一個字符串中的空格替換成“%20”。
例如,當字符串爲We Are Happy.則經過替換之後的字符串爲We%20Are%20Happy。
'''
def solve(string):
'Function to solve problem.'
if not isinstance(string, str):
print "invalid string"
return
string = list(string)
countBlank = 0
for item in string:
if item == ' ':
countBlank += 1
stringReplace = (len(string) + 2 * countBlank) * [None]
indexReplace = 0
for i in xrange(len(string)):
if string[i] == ' ':
stringReplace[indexReplace] = '%'
indexReplace += 1
stringReplace[indexReplace] = '2'
indexReplace += 1
stringReplace[indexReplace] = '0'
indexReplace += 1
else:
stringReplace[indexReplace] = string[i]
indexReplace += 1
print "".join(stringReplace)
def test():
'Test the program.'
string = "hello world"
solve(string)# "hello%20world"
string = " helloworld"
solve(string)# "%20helloworld"
string = 1
solve(string)# "invalid string"
string = None
solve(string)# "invalid string"
# def input():
# 'Input by hand'
# # 輸入單個數字
# x = int(raw_input())
# # 輸入兩個數字
# [n, m] = map(int, raw_input().strip().split(' '))
# # 輸入一串數字
# a = map(int, raw_input().strip().split(' '))
# # 輸入字符串
# b = list(raw_input())
# solve(x, n, m, a, b)
if __name__ == "__main__":
#input()
import time
previousTime = time.time()
test()
nowTime = time.time()
print "using %f second." % (nowTime - previousTime)
結果爲:
hello%20world
%20helloworld
invalid string
invalid string
using 0.000110 second.
可以看到這兩個程序的時間運算都是一個量級的,但前一個是後一個的68/110分之一,比1/2多一點點,由於官方程序是要遍歷兩次的,而我append是隻需遍歷一次的,但append擴展內存需要耗費一些時間,這個分析是很符合結果的。
想法1:C++現在只是懂一點點使用的方法,知道有個vector,不知道用vector的思路是不是一樣的。