Python: 每日一题 38
本帖最后由 ooxx7788 于 2017-5-5 20:18 编辑有一个车的里程表是以整数方式显示的,但是有个毛病,每到4时会直接跳至5,例如3后面本应该显示4,但是直接显示为5。
那么当显示为13公里的时候,实际上是12公里。(因为4被跳了。)
而当显示为15公里的时候,实际上是13公里。(因为4和14被跳了。)
现在请给出一个函数,当输入显示公里数时,返回实际公里数。
有人表示有答案会影响自己的思路,所以答案将延迟放出(我会告诉你,其实是我没做出来吗?)。
给出测试代码,test.py请在每日一题33,34中查看。
test.assert_equals(faulty_odometer(13), 12)
test.assert_equals(faulty_odometer(15), 13)
test.assert_equals(faulty_odometer(55), 40)
test.assert_equals(faulty_odometer(2005), 1462)
test.assert_equals(faulty_odometer(1500), 1053)
test.assert_equals(faulty_odometer(999999), 531440)
test.assert_equals(faulty_odometer(165826622), 69517865)
更新答案。
**** Hidden Message ***** 本帖最后由 jerryxjr1220 于 2017-5-4 21:58 编辑
def count(n):
real, show = 0, 0
while show < n:
real += 1
show += 1
while '4' in str(show):
show += 1
else:
return real
这个是最偷懒的写法,实际上有更好的算法,比如第几位出现4就跳过多少数,懒得算了,手机随便写写。 jerryxjr1220 发表于 2017-5-4 21:50
这个是最偷懒的写法,实际上有更好的算法,比如第几位出现4就跳过多少数,懒得算了,手机随便写写。
这算法就是模拟实际发生情况,思路上倒是很有意思。
缺陷就是如果n给一个很大的数字,比如千万以上的数字,效率就有点太低了。
不过随便写写,就能写出这样的,很厉害! 本帖最后由 jerryxjr1220 于 2017-5-5 06:48 编辑
ooxx7788 发表于 2017-5-4 22:02
这算法就是模拟实际发生情况,思路上倒是很有意思。
缺陷就是如果n给一个很大的数字,比如千万以上的 ...
是的,这就是我说的缺陷。
优化的算法就是根据4出现的位置,直接跳过多少数字,这样效率就会高很多。
个位出现4 就加1, 十位出现4就加10,百位出现4就加100,以此类推。
提供思路,写就不写了,我去看美剧了{:10_256:}
def count(n):
real, show = 0, 0
while show<n:
real += 1
show += 1
while '4' in str(show):
show += 10**list(str(show))[::-1].index('4')
else:
return real
只改了1行 本帖最后由 jerryxjr1220 于 2017-5-5 07:06 编辑
其实还能继续优化,不需要每次+1,可以每次+10或者+100或者+1000,这样可以更快.
显示的数每次+10,实际数每次+9
显示数每次+100,实际数每次+81,以此类推。
实际上,这样最终优化的结果就是只要根据你输入的数字,比如999,转化为列表【9,9,9】
提取百位的数字9(比4大的要-1),十位数字9(比4大的要-1),个位数字9(比4大的要-1),那么直接可以得到答案 81×(9-1)+ 9×(9-1)+ (9-1) = 728
以此类推,这样就不需要循环了,直接出答案,最快{:10_256:} jerryxjr1220 发表于 2017-5-5 06:55
其实还能继续优化,不需要每次+1,可以每次+10或者+100或者+1000,这样可以更快.
显示的数每次+10,实际数 ...
是的,我更新的答案里面,其实有人用了更聪明的办法,直接把数字变成9进制。就是你这个想法的延伸了。 这样对吗
def real_num(num):
n=4
i=0
while num>=n:
print 'num:%s,n:%s'%(num,n)
n+=10
i+=1
return num-i
18813034116 发表于 2017-5-5 22:12
这样对吗
Success!
Success!
Fail!49 not equals 40
Fail!1804 not equals 1462
Fail!1350 not equals 1053
Fail!899999 not equals 531440
Fail!149243960 not equals 69517865
不对哦! 本帖最后由 当回首遇上转身 于 2017-5-6 02:23 编辑
楼主,显示路程数不可能有49、1804、149243960出现吧?
应该显示的是59、1805、159253960才对啊
你发这样有悖论可能的调试,我写了代码也不敢发 本帖最后由 当回首遇上转身 于 2017-5-6 03:11 编辑
先发个简单的{:10_256:} Powered by: Python 3.5.2
import os
while 1:
showGL = int(input("请输入显示公里:"))
temp, factGL = 0, 0
while temp < showGL:
temp += 1
factGL += 1
temp =int((str(temp)).replace('4','5'))
print("实际公里:",factGL)
调试信息:
请输入显示公里:55
实际公里:40
请输入显示公里:2005
实际公里:1462
请输入显示公里:1500
实际公里:1053
请输入显示公里:999999
实际公里:531440
请输入显示公里:165826622
实际公里:69517865
这种递进的坏处就是数位比较大后之后很呵呵{:10_269:}
而且要一直在字符和整型数之间转换也很影响系统效率 当回首遇上转身 发表于 2017-5-6 02:08
楼主,显示路程数不可能有49、1804、149243960出现吧?
应该显示的是59、1805、159253960才对啊
49是他算出来的结果。并不是显示数字。 本帖最后由 当回首遇上转身 于 2017-5-6 08:59 编辑
ooxx7788 发表于 2017-5-6 07:43
49是他算出来的结果。并不是显示数字。
fair enough, my mistake 很简单啊,直接把包含4的数字的个数减掉不就行了
def getnum(num):
fours =
return num-len(fours) def real_num(num):
count = 0
for i in range(1,num):
stl = str(i)
if '4' in stl:
count += 1
print(num - count)
real_num(165826622) 其实就是变相的九进制
yz=(0,1,2,3,0,4,5,6,7,8)
def jiu(s):
s=str(s)
l=len(s)
k=0
for i in range(l):
k+=yz)]*(9**(l-i-1))
return k
print(jiu(165826622)) 为什么我为了写九进制稀里哗啦写了这么多,原来还有直接替换和int带第二参数的一条搞定的啊{:10_266:}
余欲渔 发表于 2017-5-10 09:27
为什么我为了写九进制稀里哗啦写了这么多,原来还有直接替换和int带第二参数的一条搞定的啊
{:10_297:} 1 {:10_254:} willLin 发表于 2017-5-15 15:08
光看,不写是不行的。