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 练习题总结(待续)的更多相关文章

  1. Python练习题 028:求3*3矩阵对角线数字之和

    [Python练习题 028] 求一个3*3矩阵对角线元素之和 ----------------------------------------------------- 这题解倒是解出来了,但总觉得 ...

  2. Python练习题 027:对10个数字进行排序

    [Python练习题 027] 对10个数字进行排序 --------------------------------------------- 这题没什么好说的,用 str.split(' ') 获 ...

  3. Python练习题 026:求100以内的素数

    [Python练习题 026] 求100以内的素数. ------------------------------------------------- 奇怪,求解素数的题,之前不是做过了吗?难道是想 ...

  4. Python练习题 025:判断回文数

    [Python练习题 025] 一个5位数,判断它是不是回文数.即12321是回文数,个位与万位相同,十位与千位相同. ---------------------------------------- ...

  5. Python练习题 024:求位数及逆序打印

    [Python练习题 024] 给一个不多于5位的正整数,要求:一.求它是几位数,二.逆序打印出各位数字. ---------------------------------------------- ...

  6. Python练习题 004:判断某日期是该年的第几天

    [Python练习题 004]输入某年某月某日,判断这一天是这一年的第几天? ---------------------------------------------- 这题竟然写了 28 行代码! ...

  7. Python练习题-1.使用匿名函数对1~1000求和,代码力求简洁。

    Python 练习 标签(空格分隔): Python Python练习题 Python知识点 一.使用匿名函数对1~1000求和,代码力求简洁. 答案: In [1]: from functools ...

  8. PYTHON练习题 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数。

    Python 练习 标签: Python Python练习题 Python知识点 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数,如果大于预设的 ...

  9. python 基础 2.8 python练习题

    python 练习题:   #/usr/bin/python #coding=utf-8 #@Time   :2017/10/26 9:38 #@Auther :liuzhenchuan #@File ...

随机推荐

  1. 【Java】Javadoc的使用

    一.名词解释 javadoc是从程序源代码中抽取类.方法.成员等注释形成一个和源代码配套的API帮助文档.也就是说,只要在编写程序时以一套特定的标签作注释,在程序编写完成后,通过Javadoc就可以同 ...

  2. Listener中@Autowired无法注入的问题

    最近在用监听器的时候遇到了spring无法注入的问题,代码如下,这个task总是null,包明明已经被扫到了,就是注入不进来. public class MyListener implements S ...

  3. 基于pg_qualstats和hypopg的自动索引调优

    pg-qualstats的安装和配置 1.安装pg-qualstats -pg-qualstats 2.将pg_qualstats和pg_stat_statements添加到shared_preloa ...

  4. glog的安装使用

    参考 :https://blog.csdn.net/Pig_Pig_Bang/article/details/81632962 https://blog.csdn.net/cywtd/article/ ...

  5. 使用JSP/Servalet技术开发新闻发布系统------动态网页开发基础

    什么是动态网页? 动态网页是指在服务器端运行的程序或者网页,它们会随不同客户.不同时间,返回不同的网页. 动态网页的特点? (1).交互性:即网页会根据用户的要求和选择而动态改变和响应.采用动态网页技 ...

  6. Linux 理解 %iowait (%wio)

    理解 %iowait (%wio) 2016/02/25 %iowait 是 “sar -u” 等工具检查CPU使用率时显示的一个指标,在Linux上显示为 %iowait,在有的Unix版本上显示为 ...

  7. 题解 CF375D 【Tree and Queries】

    首先,子树上的查询问题可以通过$DFS$序转为序列问题 再一看,没有修改,可以离线,这不就是莫队吗? 我们用$sum_i$表示出现次数$\geq i$的个数 用$val_i$表示第$i$种颜色的出现次 ...

  8. PHP全栈学习笔记23

    php,基础,流程控制,函数,字符串,数组,web交互,mysql数据库,PHP数据库编程,cookie与session,日期和时间,图形图形处理,文件和目录处理,面向对象,pdo数据库抽象层,sma ...

  9. 在默认使用apache中央仓库时, 报错 protocol_version

    https://cloud.tencent.com/developer/ask/136221/answer/241408 2018年6月,为了提高安全性和符合现代标准,不安全的TLS 1.0和1.1协 ...

  10. @ResponseBody 中文乱码 问题

    这篇博文针对的是以下的情形: 当@ResponseBody 的对象是个蕴含中文的实体对象时,一切正常,当@ResponseBody 的对象是个中文String时,接收到乱码. (如果连前半句话的情况都 ...