写在开头的话:
当想写这个的时候,发现已经有人做了这个工作了,详情请见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的思路是不是一样的。