11. 数字颠倒 12. 字符串反转
- 输入一个整数,将这个整数以字符串的形式逆序输出
- 程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001
- 输入:输入一个int整数
- 输出:将这个整数以字符串的形式逆序输出
示例:
输入
1516000
输出
0006151
思路:
字符串反转
代码实现:
str_num = str(input())
print(str_num[::-1])
13. 句子逆序
- 将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”
所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符 - 输入:将一个英文语句以单词为单位逆序排放。
- 输出:得到逆序的句子
示例:
输入
I am a boy
输出
boy a am I
思路:
将每个单词放入列表,列表逆序,再使用join()函数转为字符串
代码实现:
sentence_list = input().split(' ')
reverse_list = sentence_list[::-1]
print(' '.join(reverse_list))
14. 字串的连接最长路径查找
- 给定n个字符串,请对n个字符串按照字典序排列。
- 输入:输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。
- 输出:数据输出n行,输出结果为按照字典序排列的字符串。
示例:
输入
9
cap
to
cat
card
two
too
up
boat
boot
输出
boat
boot
cap
card
cat
to
too
two
up
思路:
使用sorted()函数排序
代码实现:
import sys
while True:
try:
n = int(sys.stdin.readline())
lst = []
for i in range(n):
lst.append(sys.stdin.readline().strip())
sort_list = sorted(lst)
for i in sort_list:
print(i)
except:
break
15. 求int型正整数在内存中存储时1的个数
- 输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。
- 输入:输入一个整数(int类型)
- 输出:这个数转换成2进制后,输出1的个数
示例:
输入
5
输出
2
思路:
十进制转二进制:
用十进制整数除以2,余数作为二进制字符首位,将商再除以2,余数作为二进制字符第二位,重复过程,直到商为0
代码实现:
num = int(input())
i_str = ''
while num != 0:
i_str += str(num % 2)
num //= 2
print(i_str.count('1'))
16. 购物单
- 王强今天很开心,公司发给N元的年终奖。王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:
如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。王强想买的东西很多,为了不超出预算,他把每件物品规定了一个重要度,分为 5 等:用整数 1 ~ 5 表示,第 5 等最重要。他还从因特网上查到了每件物品的价格(都是 10 元的整数倍)。他希望在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
设第 j 件物品的价格为 v[j] ,重要度为 w[j] ,共选中了 k 件物品,编号依次为 j 1 , j 2 ,……, j k ,则所求的总和为:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 为乘号)
请你帮助王强设计一个满足要求的购物单。
17. 坐标移动
- 开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。
输入:
合法坐标为A(或者D或者W或者S) + 数字(两位以内)
坐标之间以;分隔。
非法坐标点需要进行丢弃。如AA10; A1A;
; YAD; 等。
下面是一个简单的例子 如:
A10;S20;W10;D30;X;A1A;B10A11;;A10;
处理过程:
起点(0,0)
- A10 = (-10,0)
- S20 = (-10,-20)
- W10 = (-10,-10)
- D30 = (20,-10)
- x = 无效
- A1A = 无效
- B10A11 = 无效
- 一个空 不影响
- A10 = (10,-10)
结果 (10, -10)
- 输入:一行字符串
- 输出:最终坐标,以,分隔
示例:
输入
A10;S20;W10;D30;X;A1A;B10A11;;A10;
输出
10,-10
思路:
将字符串按照分号 “ ; ” 分割,遍历每一个片段,使用re匹配
代码实现:
import sys
import re
while True:
try:
origin = [0, 0]
move_list = input().strip().split(';')
for i in move_list:
ret = re.match(r'^([WASD])([0-9]?[0-9])$', i)
if ret:
if ret.group(1) == 'W':
origin[1] += int(ret.group(2))
elif ret.group(1) == 'S':
origin[1] -= int(ret.group(2))
elif ret.group(1) == 'A':
origin[0] -= int(ret.group(2))
elif ret.group(1) == 'D':
origin[0] += int(ret.group(2))
else:
continue
print(str(origin[0])+','+str(origin[1]))
except:
break
18. 识别有效的IP地址和掩码并进行分类统计
- 请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255
私网IP范围是:
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255
子网掩码中每个数字都为8位二进制,总体要求前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
注意二进制下全是1或者全是0均为非法
注意:
- 类似于【0...*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
- 私有IP地址和A,B,C,D,E类地址是不冲突的
- 输入:多行字符串。每行一个IP地址和掩码,用~隔开。
- 输出:统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
示例:
输入
10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0
输出
1 0 1 0 0 2 1
思路:
先判断子网掩码,若不通过,直接计错误并进行下一循环。
子网掩码只能从 [‘255’, ‘254’, ‘252’, ‘248’, ‘240’, ‘224’, ‘192’, ‘128’, ‘0’] 中取。
代码实现:
import sys
A, B, C, D, E, err, pri = 0, 0, 0, 0, 0, 0, 0
while True:
try:
ip_subnet = sys.stdin.readline().strip().split('~')
ip = ip_subnet[0]
subnet = ip_subnet[1]
# 判断子网掩码
subnet_mask = True
subnet_list = subnet.split('.')
# 将子网掩码变为二进制,拼成字符串
subnet_first = bin(int(subnet_list[0]))[2:]
subnet_second = bin(int(subnet_list[1]))[2:]
subnet_third = bin(int(subnet_list[2]))[2:]
subnet_forth = bin(int(subnet_list[3]))[2:]
subnet_str = subnet_first + subnet_second + subnet_third + subnet_forth
# 判断子网掩码是否都为1或都为零
if subnet_str.count('1') == 0 or subnet_str.count('0') == 0:
subnet_mask = False
err += 1
continue
# 判断是否1之后都是0
zero_index = subnet_str.index('0')
for i in range(zero_index, len(subnet_str)):
if subnet_str[i] == '1':
subnet_mask = False
break
# 判断子网掩码是否在['255', '254', '252', '248', '240', '224', '192', '128', '0']内
subnet_str_lst = [subnet_first, subnet_second, subnet_third, subnet_forth]
for i in subnet_str_lst:
if i not in [bin(255)[2:], bin(254)[2:], bin(252)[2:], bin(248)[2:], bin(240)[2:], bin(224)[2:], bin(192)[2:], bin(128)[2:], '0']:
subnet_mask = False
break
if not subnet_mask:
err += 1
continue
# 判断ip类型
ipA = ipB = ipC = ipD = ipE = error = private = False
ip_list = ip.split('.')
ip_first = int(ip_list[0])
ip_second = int(ip_list[1]) if len(ip_list[1]) else ''
ip_third = int(ip_list[2]) if len(ip_list[2]) else ''
ip_forth = int(ip_list[3]) if len(ip_list[3]) else ''
if ip_first != '' and ip_second != '' and ip_third != '' and ip_forth != '':
if 1 <= ip_first <= 126 and 0 <= ip_second <= 255 and 0 <= ip_third <= 255 and 0 <= ip_forth <= 255:
A += 1
elif 128 <= ip_first <= 191 and 0 <= ip_second <= 255 and 0 <= ip_third <= 255 and 0 <= ip_forth <= 255:
B += 1
elif 192 <= ip_first <= 223 and 0 <= ip_second <= 255 and 0 <= ip_third <= 255 and 0 <= ip_forth <= 255:
C += 1
elif 224 <= ip_first <= 239 and 0 <= ip_second <= 255 and 0 <= ip_third <= 255 and 0 <= ip_forth <= 255:
D += 1
elif 240 <= ip_first <= 255 and 0 <= ip_second <= 255 and 0 <= ip_third <= 255 and 0 <= ip_forth <= 255:
E += 1
# 判断私有ip
if ip_first == 10 and 0 <= ip_second <= 255 and 0 <= ip_third <= 255 and 0 <= ip_forth <= 255 \
or ip_first == 172 and 16 <= ip_second <= 31 and 0 <= ip_third <= 255 and 0 <= ip_forth <= 255 \
or ip_first == 192 and ip_second == 168 and 0 <= ip_third <= 255 and 0 <= ip_forth <= 255:
pri += 1
else:
err += 1
except:
break
print("%s %s %s %s %s %s %s" % (A, B, C, D, E, err, pri))
19. 简单错误记录
- 开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1、 记录最多8条错误记录,循环记录(或者说最后只输出最后出现的八条错误记录),对相同的错误记录(净文件名称和行号完全匹配)只记录一条,错误计数增加;
2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
3、 输入的文件可能带路径,记录文件名称不能带路径。 - 输入:一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
- 输出:将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开。
示例:
输入:
G:\rp\onajqj\maahmq 631
E:\njfgjkcrh 641
C:\co\zk\ao\bxgxjfgrwckfxekeqro 629
D:\mf\si\jmfdahkeffyjjsf 646
……
G:\zsw\uewu\arefkiz 634
E:\ja\zg\njfgjkcrh 644
D:\gfute\ju\wuy\szxcdhlaytgj 636
C:\mpgcx\kcgi\arefkiz 645
C:\zayn\jmfdahkeffyjjsf 648
F:\kkplu\avvw\hbzmwj\jmfdahkeffyjjsf 648
E:\maahmq 631
E:\hs\xnto\jmfdahkeffyjjsf 645
G:\cqekvaxypemktyurn 633
D:\maahmq 646
E:\jmfdahkeffyjjsf 636
G:\hbvm\szxcdhlaytgj 642
输出
szxcdhlaytgj 636 1
arefkiz 645 1
jmfdahkeffyjjsf 648 2
jmfdahkeffyjjsf 645 1
qekvaxypemktyurn 633 1
maahmq 646 1
jmfdahkeffyjjsf 636 1
szxcdhlaytgj 642 1
注意maahmq 631 已经在第一个出现过,因此后面再出现时,将其加在第一个上,即不在最后8个结果中出现
思路:
因为此处有三个变量:文件名、行号、出现次数
因此我们可以将‘文件名 行号’作为字典的键,出现次数作为值,进行累加
代码实现:
import sys
hash_map = {}
error_log = []
while True:
try:
s_list = sys.stdin.readline().strip().split()
file_name = s_list[0].split('\\')[-1]
max_filename = file_name[-16:]
error_line = s_list[1]
log = max_filename + ' ' + error_line
if log not in hash_map:
hash_map[log] = 1
error_log.append(log)
else:
hash_map[log] += 1
except:
break
for i in error_log[-8:]:
print(i + ' ' + str(hash_map[i]))
20. 密码验证合格程序
- 密码要求:
1.长度超过8位
2.包括大小写字母.数字.其它符号,以上四种至少三种
3.不能有长度大于2,且相同的子串出现
说明:长度超过2的子串 - 输入:一组或多组长度超过2的子符串。每组占一行
- 输出:如果符合要求输出:OK,否则输出NG
示例:
输入
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000
输出
OK
NG
NG
OK
思路1
1, 2要求不难实现,对于3,可使用列表切片三个三个向后切,每切一次,将其放入哈希表,若在哈希表中遇到同样切片,输出NG
代码实现1
import sys
while True:
try:
s = input().strip()
# 长度超过8位
if len(s) <= 8:
print('NG')
continue
# 至少三种字符
num = upper = lower = other = 0
for i in s:
if '0' <= i <= '9':
num = 1
elif 'A' <= i <= 'Z':
upper = 1
elif 'a' <= i <= 'z':
lower = 1
else:
other = 1
if num + upper + lower + other < 3:
print('NG')
continue
# 相同长度超2的子串
hash_map = {}
sub_str = True
for i in range(3, len(s)):
if s[i-3:i] not in hash_map:
hash_map[s[i-3:i]] = 1
else:
print('NG')
sub_str = False
break
if not sub_str:
continue
# 都通过
print('OK')
except:
break
思路2:正则表达式
反向引用:
- 例:
当一条字符串中含有2(组/个)连续的字符时,该字符串可以称之为“连续的字符串”。
比如:2034384538452可以成为“连续的字符串”,因为其含有2次连续的3845。
请找出能够判断“连续的字符串”的方法,输入可以用字符串或数组,输入不能为空,并且字符串长度必须大于等于1。
import re
re.compile(r'(.+)\1').search
表达式在匹配时,表达式引擎会将小括号 “( )” 包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。
“\1” 引用第1对括号内匹配到的字符串,”\2” 引用第2对括号内匹配到的字符串……以此类推。
如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 “(“ 在前,那这一对为先。
回归题目:
a中[ (.{3,}).* ]是指[(3-n个任意字符)跟随(任意个任意字符)]这一[组合],\1表示向前引用,所以正则表达式的形式为[组合]…[组合],在s中寻找这一形式是否存在,返回值赋予给a
代码实现2:
import re
while True:
try:
s = input()
a = re.findall(r'(.{3,}).*\1', s) # 只匹配到一个不出现结果
b1 = re.findall(r'\d', s)
b2 = re.findall(r'[A-Z]', s)
b3 = re.findall(r'[a-z]', s)
b4 = re.findall(r'[^0-9A-Za-z]', s)
# 如果re.findall()未匹配到,则返回空列表,
# b1-b4至多有一个空列表,保证b1-b4至少三个有匹配结果
# 为保证长度大于2,且相同的子串不出现,要求a中不能出现结果
ret = 'OK' if ([b1, b2, b3, b4].count([]) <= 1 and a == [] and len(s) > 8) else 'NG'
print(ret)
except:
pass