鱼C论坛

 找回密码
 立即注册
查看: 6355|回复: 56

[技术交流] Python: 每日一题 38

[复制链接]
发表于 2017-5-4 18:57:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 ooxx7788 于 2017-5-5 20:18 编辑

有一个车的里程表是以整数方式显示的,但是有个毛病,每到4时会直接跳至5,例如3后面本应该显示4,但是直接显示为5。
那么当显示为13公里的时候,实际上是12公里。(因为4被跳了。)
而当显示为15公里的时候,实际上是13公里。(因为4和14被跳了。)

现在请给出一个函数,当输入显示公里数时,返回实际公里数。

有人表示有答案会影响自己的思路,所以答案将延迟放出(我会告诉你,其实是我没做出来吗?)。

给出测试代码,test.py请在每日一题33,34中查看。
  1. test.assert_equals(faulty_odometer(13), 12)
  2. test.assert_equals(faulty_odometer(15), 13)
  3. test.assert_equals(faulty_odometer(55), 40)
  4. test.assert_equals(faulty_odometer(2005), 1462)
  5. test.assert_equals(faulty_odometer(1500), 1053)
  6. test.assert_equals(faulty_odometer(999999), 531440)
  7. test.assert_equals(faulty_odometer(165826622), 69517865)
复制代码


更新答案。
游客,如果您要查看本帖隐藏内容请回复

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-5-4 21:50:00 From FishC Mobile | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-5-4 21:58 编辑
  1. def count(n):
  2.   real, show = 0, 0
  3.   while show < n:
  4.     real += 1
  5.     show += 1
  6.     while '4' in str(show):
  7.       show += 1
  8.   else:
  9.     return real
复制代码

这个是最偷懒的写法,实际上有更好的算法,比如第几位出现4就跳过多少数,懒得算了,手机随便写写。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-4 22:02:43 | 显示全部楼层
jerryxjr1220 发表于 2017-5-4 21:50
这个是最偷懒的写法,实际上有更好的算法,比如第几位出现4就跳过多少数,懒得算了,手机随便写写。


这算法就是模拟实际发生情况,思路上倒是很有意思。
缺陷就是如果n给一个很大的数字,比如千万以上的数字,效率就有点太低了。
不过随便写写,就能写出这样的,很厉害!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-4 22:05:00 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-5-5 06:48 编辑
ooxx7788 发表于 2017-5-4 22:02
这算法就是模拟实际发生情况,思路上倒是很有意思。
缺陷就是如果n给一个很大的数字,比如千万以上的 ...


是的,这就是我说的缺陷。
优化的算法就是根据4出现的位置,直接跳过多少数字,这样效率就会高很多。
个位出现4 就加1, 十位出现4就加10,百位出现4就加100,以此类推。
提供思路,写就不写了,我去看美剧了

  1. def count(n):
  2.     real, show = 0, 0
  3.     while show<n:
  4.         real += 1
  5.         show += 1
  6.         while '4' in str(show):
  7.             show += 10**list(str(show))[::-1].index('4')
  8.     else:
  9.         return real
复制代码

只改了1行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-5 06:55:55 | 显示全部楼层
本帖最后由 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
以此类推,这样就不需要循环了,直接出答案,最快
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-5 20:20:09 | 显示全部楼层
jerryxjr1220 发表于 2017-5-5 06:55
其实还能继续优化,不需要每次+1,可以每次+10或者+100或者+1000,这样可以更快.
显示的数每次+10,实际数 ...

是的,我更新的答案里面,其实有人用了更聪明的办法,直接把数字变成9进制。就是你这个想法的延伸了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-5 22:12:32 | 显示全部楼层
这样对吗
  1. def real_num(num):
  2.     n=4
  3.     i=0
  4.     while num>=n:
  5.       
  6.         print 'num:%s,n:%s'%(num,n)
  7.         n+=10
  8.         i+=1
  9.     return num-i
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-5 22:18:43 | 显示全部楼层


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

不对哦!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-6 02:08:47 | 显示全部楼层
本帖最后由 当回首遇上转身 于 2017-5-6 02:23 编辑

360截图20170506020813372.jpg
楼主,显示路程数不可能有49、1804、149243960出现吧?
应该显示的是59、1805、159253960才对啊

你发这样有悖论可能的调试,我写了代码也不敢发
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-6 02:35:37 | 显示全部楼层
本帖最后由 当回首遇上转身 于 2017-5-6 03:11 编辑

先发个简单的      Powered by: Python 3.5.2
  1. import os

  2. while 1:
  3.     showGL = int(input("请输入显示公里:"))
  4.     temp, factGL = 0, 0
  5.     while temp < showGL:
  6.         temp += 1
  7.         factGL += 1
  8.         temp =  int((str(temp)).replace('4','5'))
  9.     print("实际公里:",factGL)
复制代码

调试信息:
  1. 请输入显示公里:55
  2. 实际公里:40
  3. 请输入显示公里:2005
  4. 实际公里:1462
  5. 请输入显示公里:1500
  6. 实际公里:1053
  7. 请输入显示公里:999999
  8. 实际公里:531440
  9. 请输入显示公里:165826622
  10. 实际公里:69517865
复制代码


这种递进的坏处就是数位比较大后之后很呵呵
而且要一直在字符和整型数之间转换也很影响系统效率
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-6 07:43:49 From FishC Mobile | 显示全部楼层
当回首遇上转身 发表于 2017-5-6 02:08
楼主,显示路程数不可能有49、1804、149243960出现吧?
应该显示的是59、1805、159253960才对啊


49是他算出来的结果。并不是显示数字。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-6 08:58:07 | 显示全部楼层
本帖最后由 当回首遇上转身 于 2017-5-6 08:59 编辑
ooxx7788 发表于 2017-5-6 07:43
49是他算出来的结果。并不是显示数字。


fair enough, my mistake
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-8 10:22:12 | 显示全部楼层
很简单啊,直接把包含4的数字的个数减掉不就行了
  1. def getnum(num):
  2.   fours = [i for i in range(1,num+1) if "4" in str(i)]
  3.   return num-len(fours)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-8 16:05:08 | 显示全部楼层
  1. def real_num(num):
  2.     count = 0
  3.     for i in range(1,num):
  4.         stl = str(i)
  5.         if '4' in stl:
  6.             count += 1
  7.     print(num - count)
  8. real_num(165826622)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 09:14:51 | 显示全部楼层
其实就是变相的九进制
  1. yz=(0,1,2,3,0,4,5,6,7,8)
  2. def jiu(s):
  3.     s=str(s)
  4.     l=len(s)
  5.     k=0
  6.     for i in range(l):
  7.         k+=yz[int(s[i])]*(9**(l-i-1))
  8.     return k
  9.       
  10. print(jiu(165826622))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 09:27:32 | 显示全部楼层
为什么我为了写九进制稀里哗啦写了这么多,原来还有直接替换和int带第二参数的一条搞定的啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-10 09:42:33 | 显示全部楼层
余欲渔 发表于 2017-5-10 09:27
为什么我为了写九进制稀里哗啦写了这么多,原来还有直接替换和int带第二参数的一条搞定的啊

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-10 11:41:18 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-5-15 15:08:44 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-5-15 16:11:20 | 显示全部楼层

光看,不写是不行的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 12:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表