Python 练习题总结(待续)
1、编写一个函数,接受一个参数n,n为正整数,左右两种打印方 式。要求数字必须对齐
正三角
倒三角
实现思路:
思路1、一行一行打印,前面追加空格,每一个空格的宽度等于数字字符串的宽度
#正三角打印
def triangle(k):
for a in range(1,k+1): a =1
for b in range(k,0,-1): a=15
if a < b:
print(' '*len(str(b)),end=' ')
else:
print(b,end=' ') print()
思路2、切割打印,首先每个数字隔一个空格,获取长度,当遇到遇到一个空格,就把前面全部补成空格后面数字和空格全部打印。
#正三角打印
def triangle2(n):
tail=" ".join([str(i) for i in range(n,0,-1)])
width = len(tail)
for i in range(-1,-width,-1):
if tail[i] == ' ':#
print(' '*(width+i),tail[i+1:])
print(tail)
#倒三角打印
def triangle1(n):
tail=" ".join([str(i) for i in range(n,0,-1)])
print(tail)
for i in range(len(tail)):
if tail[i] == ' ':
print(' '*i,tail[i+1:])
2、阶乘解法
思路分析:
阶乘即n!=1×2×3×...×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。
1、函数解法
#方法1
def fac(n):
if n == 1:
return 1
return n * fac(n-1)
print(fac(4)) #方法2
def fac1(n,fac=1): #n=4 fac=1 #n=3,fac=4 #n=2,fac=12 #n=1 fac=24
if n == 1: #4 3 2 1
return fac #
fac = fac * n # fac=4 #fac = 12 #fac=24
return fac1(n-1,fac) # fac(3,4) #fac(2,12) #fac(1,24)
print(fac1(4))
2、for 循环解法
fac = 1
for a in range(1,5):
fac *= a
print(fac)
3、猴子吃桃
思路分析:
#假设猴子摘x个桃
d1 x //2 - 1
d2 d1//2 - 1
d3 d2//2 - 1
...
d9 d8//2 - 1
d10 1
#猴子偷桃
"""
猴子第一天摘下若干桃子,当即吃了一半,还不过瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。
以后每天早上又将剩下的桃子吃掉一半,又多吃一个。以后每天早上都吃前一天剩下的一半零一个。到第10天早上想吃的时候,
只剩下一个桃子,求第一天工摘多少桃子
"""
def peach(days=10):
if days == 1:
return 1
return 2*(peach(days-1)+1)
print(peach(days=10))
4、将一个数逆序放入列表中,例如:1234 -->[4,3,2,1]
#方法一 递归切片
def revert(x,data=[]):
if x:
data.append(x[-1])
revert(x[:-1])
return data
print(revert("98adad123"))
#方法二 使用数字整除取模递归
def revert(x, target=None): #x="123045" #12304 [5,]
if target is None:
target = [] #target = []
x, y = divmod(x, 10) # x=12304 y=5 # x=1230 y=4
target.append(y) #target = [5,] #[5,4]
if x == 0:
return target
return revert(x, target) #12304 [5,] #1230 [5,4]
print(revert(123045))
5、字典扁平化(主要练习递归)
源字典 {'a':{'b':1,'c':2}, 'd':{'e':3,'f':{'g':4}}} 目标字典 {'a.c': 2, 'd.e': 3, 'd.f.g': 4, 'a.b': 1}
src={"a":{"b":1,"c":2},"d":{"e":4,"f":{"g":3}}}
def dst(src:dict,prekey="",targetdct = {}):
for k,v in src.items():
if isinstance(v,dict):
prekey=prekey + k + "."
dst(v,prekey)
prekey = ""
else:
targetdct[prekey + k] = v
#
return targetdct
print(dst(src))
6、实现base64编码
Base64编码核心思想: 每3个字节断开,拿出一个3个字节,每6个bit断开成4段。 因为每个字节其实只占用了6 位, 2**6 = 64 ,因此有了base64的编码表。 每一段当做一个8bit看它的值,这个值就是Base64编码表的索引 值,找到对应字符。 再取3个字节,同样处理,直到最后。
举例: abc对应的ASCII码为:0x61 0x62 0x63 01100001 01100010 01100011 # abc 011000 010110 001001 100011 00011000 00010110 00001001 00100011 # 每6位补齐为8位 24 22 9 35
问题: 一个字节能变成几个Base64的字节? 两个字节能变成几个Base64的字节? 字符串'`'反引号如何处理? 末尾的处理? 1、正好3个字节,处理方式同上 2、剩1个字节或2个字节,用0补满3个字节 3、补0的字节用=表示
alphabet = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
def base64encode(src:str):
ret = bytearray()
if isinstance(src, str):
_src = src.encode()
else:
return
length = len(_src) r = 0
for offset in range(0, length, 3):
triple = _src[offset:offset + 3] # 切片边界可以超界
# print(triple)
if offset + 3 > length:
r = 3 - len(triple)
triple += b'\x00' * r # 便于计算先补零
b = int.from_bytes(triple, 'big')
for i in range(18, -1, -6):
if i == 18:
index = b >> i
else:
index = b >> i & 0x3F # 0b11 1111
ret.append(alphabet[index]) # 索引查表
if r:
ret[-r:] = b'=' * r # 从索引-r到末尾使用右边的多个元素依次替换
return bytes(ret)
import base64
strlist = ['a', '`', 'ab', 'abc', 'abcd', "ManMa", '教育a']
for x in strlist:
print(x)
print(base64encode(x))
print()
7、求2个字符串的最长公共子串
思考: s1 = 'abcdefg' s2 = 'defabcd'
方法一:矩阵算法 让s2的每一个元素,去分别和s1的每一个元素比较,相同就是1,不同就是0,有下面的矩阵
s1 | |
s1 | 0001000 |
s1 | 0000100 |
s1 | 0000010 |
s1 | 1000000 |
s1 | 0100000 |
s1 | 0010000 |
s1 | 0001000 |
上面都是s1的索引。 看与斜对角线平行的线,这个线是穿过1的,那么最长的就是最长子串。 print(s1[3:3+3]) print(s1[0:0+4]) 最长
矩阵求法,需要一个字符扫描最长子串的过程,扫描的过程就是len(s1) * len(s2)次,O(n * m),这是必须的。 难 道还需要遍历一遍找出谁才是最长的吗?能够在求矩阵过程中就找出最长的子串吗? 0001000 第一行,索引为 (3,0)。 第二行的时候如果索引(4,1)处是1,就判断(3,0)处是否为1,为1就把(3,0)处加1。 第二行的时候如果索引 (5,2)处是1,就判断(4,1)处是否为1,是1就加1,再就判断(3,0)处是否为1,为1就把(3,0)加1。
s1 | |
s1 | 0003000 |
s1 | 0000200 |
s1 | 0000010 |
s1 | 4000000 |
s1 | 0300000 |
s1 | 0020000 |
s1 | 0001000 |
上面的方法是个递归问题,不好。 最后在矩阵中找到最大的元素,从它开始就能写出最长的子串了。 但是这个不 好算,因为是逆推的,改为顺推。
s1 | |
s1 | 0001000 |
s1 | 0000200 |
s1 | 0000030 |
s1 | 1000000 |
s1 | 0200000 |
s1 | 0030000 |
s1 | 0004000 |
顺推的意思,就是如果找到一个就看前一个的数字是几,然后在它的基础上加1。
def findstr(str1:str,str2:str):
lenght1,lenght2=len(str1),len(str2)
matrix = [[0]*lenght1 for i in range(lenght2)]
#从x轴或者y轴取都可以,选择x轴,xmax和xindex
xmax = 0
xindex = 0
for i,x in enumerate(str2):
for j,y in enumerate(str1):
if x != y:
pass
else:
if i == 0 or j == 0 :
matrix[i][j] = 1
else:
matrix[i][j] = matrix[i-1][j-1] + 1 if matrix[i][j] >xmax:
xmax = matrix[i][j]
xindex = j
start = xindex + 1 - xmax
end = xindex + 1
print(matrix, xmax, xindex, start, end)
return str1[start:end]
s1 = 'abcdefg'
s2 = 'defabcd'
s2 = 'defabcdoabcdeftw'
s3 = '1234a'
s4 = ""
s5 = 'abcdd'
print(findstr(s1, s2))
print(findstr(s1, s3))
print(findstr(s1, s4))
print(findstr(s1, s5))
方法二:可不可以这样思考? 字符串都是连续的字符,所以才有了下面的思路。
思路一: 第一轮 从s1中依次取1个字符,在s2查找,看是否能够找到子串。 如果没有一个字符在s2中找到,说明 就没有公共子串,直接退出。如果找到了至少一个公共子串,则很有可能还有更长的公共子串,可以进入下一轮。
第二轮 然后从s1中取连续的2个字符,在s2中查找,看看能否找到公共的子串。如果没找到,说明最大公共子串就 是上一轮的随便的哪一个就行了。如果找到至少一个,则说明公共子串可能还可以再长一些。可以进入下一轮。
改进 其实只要找到第一轮的公共子串的索引,最长公共子串也是从它开始的,所以以后的轮次都从这些索引位置开 始,可以减少比较的次数。
思路二: 假设s1、s2两个字符串,s1短一些。 既然是求最大子串,最长子串不会超过最短的字符串,先把s1全长 作为子串。 在s2中搜索,是否返回正常的index,正常就找到了最长子串。
没有找到,把s1按照length-1取多个子串。 在s2中搜索,是否能返回正常的index。
注意: 不要一次把s1的所有子串生成,用不了,也不要从最短开始,因为题目要最长的。 但是也要注意,万一他 们的公共子串就只有一个字符,或者很少字符的,思路一就会占优势。
s1 = 'abcdefg'
s2 = 'defabcdoabcdeftw'
s3 = '1234a'
def findstr(str1:str,str2:str):
count = 0 # 计数,看看效率
if len(str2) < len(str1): # str2更短
str1, str2 = str2, str1
length = len(str1)
for sublen in range(length, 0, -1):
for start in range(0, length - sublen + 1):
substr = str1[start:start + sublen] # 切割子串
count += 1
if str2.find(substr) > -1: # found
print("count={}, substrlen={}".format(count, sublen))
return substr print(findstr(s1,s2))
print(findstr(s1,s3))
8、实现COPY函数
指定一个源文件,实现copy到目标目录
例如把/tmp/test.txt 复制到 /tmp/test1.txt
file1="/tmp/test.txt"
file2="/tmp/test1.txt" f = open(file1,"w")
lines=["abc","","jaxzhai"]
f.writelines("\n".join(lines))
#f.seek(0)
#print(f.read())
f.close()
def copy(src,dest):
with open(src) as f1:
with open(dest,"w") as f2:
f2.write(f1.read())
copy(file1,file2)
9、单词统计
有一个文件,对其进行单词统计,不区分大小写,并显示单词重复最多的10个单词
#方法1
filename = 'sample.txt'
d = {}
with open(filename, encoding='utf8') as f:
for line in f:
words = line.split()
for word in map(str.lower, words):
d[word] = d.get(word, 0) + 1
print(sorted(d.items(), key=lambda item: item[1], reverse=True))
# 或使用缺省字典
from collections import defaultdict
d = defaultdict(lambda :0)
with open(filename, encoding='utf-8') as f:
for line in f:
words = line.split()
for word in map(str.lower, words):
d[word] += 1
print(sorted(d.items(), key=lambda item: item[1], reverse=True))
这里统计的不是很全,上面的原文件是帮助文档中的path文档,path应该很多,可以通过下面代码查看:
for k in d.keys(): # 从key里面看看还有好多带有path的
if k.find('path') > -1:
print(k)
使用上面的代码,就可以看到path非常多 os.path.exists(path) 可以认为含有2个path
# 思路:遇到特殊字符,就用空格替代
def makekey(s:str):
chars = set(r"""!'"#./\()[],*-""")
key = s.lower()
ret = []
for i, c in enumerate(key):
if c in chars:
ret.append(' ')
else:
ret.append(c)
return ''.join(ret).split()
d = {}
with open('sample', encoding='utf8') as f:
for line in f:
words = line.split()
for wordlist in map(makekey, words):
for word in wordlist:
d[word] = d.get(word, 0) + 1
for k,v in sorted(d.items(), key=lambda item: item[1], reverse=True):
print(k,v)
分割key的另一种思路
def makekey1(s:str): #[os.path ]
chars = set(r"""!'"#./\()[],*-""")
key = s.lower()
ret = []
start = 0
for i, c in enumerate(key): #
if c in chars:
if start == i: # 如果紧挨着还是特殊字符,start一定等于i
start += 1 # 加1并continue
continue
ret.append(key[start:i])
start = i + 1 # 加1是跳过这个不需要的特殊字符c
else:
if start < len(key): # 小于,说明还有有效的字符,而且一直到末尾
ret.append(key[start:])
return ret d = {}
with open(filename, encoding='utf8') as f:
for line in f: #11.2. os.path — Common pathname manipulations
words = line.split() #[..,os.path,..]
for wordlist in map(makekey1, words): #[os,path]
for word in wordlist:
d[word] = d.get(word, 0) + 1
for k, v in sorted(d.items(), key=lambda item: item[1], reverse=True):
print(k, v)
Python 练习题总结(待续)的更多相关文章
- Python练习题 028:求3*3矩阵对角线数字之和
[Python练习题 028] 求一个3*3矩阵对角线元素之和 ----------------------------------------------------- 这题解倒是解出来了,但总觉得 ...
- Python练习题 027:对10个数字进行排序
[Python练习题 027] 对10个数字进行排序 --------------------------------------------- 这题没什么好说的,用 str.split(' ') 获 ...
- Python练习题 026:求100以内的素数
[Python练习题 026] 求100以内的素数. ------------------------------------------------- 奇怪,求解素数的题,之前不是做过了吗?难道是想 ...
- Python练习题 025:判断回文数
[Python练习题 025] 一个5位数,判断它是不是回文数.即12321是回文数,个位与万位相同,十位与千位相同. ---------------------------------------- ...
- Python练习题 024:求位数及逆序打印
[Python练习题 024] 给一个不多于5位的正整数,要求:一.求它是几位数,二.逆序打印出各位数字. ---------------------------------------------- ...
- Python练习题 004:判断某日期是该年的第几天
[Python练习题 004]输入某年某月某日,判断这一天是这一年的第几天? ---------------------------------------------- 这题竟然写了 28 行代码! ...
- Python练习题-1.使用匿名函数对1~1000求和,代码力求简洁。
Python 练习 标签(空格分隔): Python Python练习题 Python知识点 一.使用匿名函数对1~1000求和,代码力求简洁. 答案: In [1]: from functools ...
- PYTHON练习题 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数。
Python 练习 标签: Python Python练习题 Python知识点 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数,如果大于预设的 ...
- python 基础 2.8 python练习题
python 练习题: #/usr/bin/python #coding=utf-8 #@Time :2017/10/26 9:38 #@Auther :liuzhenchuan #@File ...
随机推荐
- Android上执行python脚本-QPython
看书,发现android可以跑python. 尝试了一下. 首先需要在手机上安装python环境,通过安装apk实现,这个apk叫QPython,还有同类的比如SL4A. QPython的官网:htt ...
- 用CSS 实现 浮动元素的 水平居中
问题描述: 基本的html结构: <div> <!-- <span>1</span> <span>2</span> <span& ...
- RocketMQ的技术亮点
高性能 存储原理 零拷贝 数据结构与存储逻辑 刷盘策略 长轮询PULL RocketMQ的Consumer都是从Broker拉消息来消费,但是为了能做到实时收消息,RocketMQ使用长轮询方式,可以 ...
- VBA字典
'字典并不存在于VBA中,需要调用 '调用方式1(前期绑定): '工具 --引用 - -浏览 - -找到scrrun.dll - 确定 '调用方式2 (后期绑定): ' Set d = CreateO ...
- 【安卓基础】ViewPager2的入门使用
之前的项目中使用过ViewPager,被坑过几次.如果你在RecyclerView中的Item使用ViewPager,你绝对会产生莫名其妙的问题,因为ViewPager在同一界面上不能有两个一样的ID ...
- 记录从裸机到TensorFlow GPU版运行 的配置过程
实验室原来有一台装Ubuntu Server系统的服务器,安装有tensorflow,在使用过程中经常出现断网.死机.自动关机等毛病,忍无可忍,决定重装系统 配置如下:Dell工作站,Xeon-E5 ...
- PHP+下载文件夹
php下载文件我整理了这三种方法,和大家分享一下: 第一种:直接添加文件下载的绝对路径连接 //如:我有一个文件在demo.xx.cn/demo.zip<button> <a ...
- Luogu4688 [Ynoi2016]掉进兔子洞 【莫队,bitset】
题目链接:洛谷 我们知道要求的是\([l_1,r_1],[l_2,r_2],[l_3,r_3]\)的可重集取交的大小,肯定是要用bitset的,那怎么做可重集呢? 那就是要稍微动点手脚,首先在离散化的 ...
- 微信H5的video标签解决方案
https://github.com/cczw2010/weixin-video 偶尔发现了可以h5化的一种更适合的方式,一个有趣的属性 h5-page 已经更新
- 前端武器库之DOM练习
1.模态对话框 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...