《劍指offer》Python語言 面試題4:替換空格

    寫在開頭的話:

    當想寫這個的時候,發現已經有人做了這個工作了,詳情請見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的思路是不是一樣的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章