难点:如何对小数点进行处理
思路
- 由于输入是字符串,可直接利用str.index('.')找到小数点位置(若无小数点,返回值为-1, 则可以此为依据写个if语句跳过小数处理部分。
- 整数的转换:使用函数从左至右依次读入两位数x,y, return:10*x+y
- 小数的转换:和整数类似,只不过return: (x+y/10)/10
- 故重点在于找到并剔除小数点,以小数点为界将字符串分为两块 int and fraction,整数部分写个小函数处理,小数部分写另一个小函数处理,最后整体返回时 return: int + fraction即可
注意!!以上思路理论上可行但小数和整数处理上过于麻烦,因为相当于要加条件判断以及写两个不同的return
A better approach:
整数和小数都使用相同函数处理(即均采用10x+y模式)只不过对小数部分,由于我们已经通过s.index()找到了小数点位置,故直接用这个位置对字符串进行切片存到两个list中去(Int and Frac),首先对两个list都利用map函数使用Int把字符串list转化为int list,之后对整数的list使用reduce(f,Int),其中f即为原步骤二中的转化函数(f(x,y) return 10x+y, 对于小数部分,我们实际上可以采用相同操作,即把它当作是整数处理,然后再把小数点移到最左端。怎样移到最左端呢?假设小数部分有n位,那么显然只要除以10**n即可, 这个n显然就是Frac list的长度。 则我们有: 对小数部分reduce(f,Frac) //变成整数串
得到整数串后 除以 10**len(Frac)即变为纯小数了,之后再返回Int+Frac即大功告成!
代码
# -*- coding: utf-8 -*-
from functools import reduce
def str2float(s):
def fn(x,y):
return x*10+y
boundary=s.index('.')
Int = list(map(int,[x for x in s[:boundary]]))
Frac = list(map(int,[x for x in s[boundary+1:]]))
return reduce(fn,Int) + reduce(fn,Frac)/(10**len(Frac))
print('str2float(\'123.456\') =', str2float('123.456'))
if abs(str2float('123.456') - 123.456) < 0.00001:
print('测试成功!')
else:
print('测试失败!')