人工智能 -- python算法之 字符串“相减”:Hash字典法的实战运用

人工智能 – python算法之 字符串“相减”:Hash字典法的实战运用

1. 引子

我们知道字符串可以相加

s1 = 'abc'
s2 = 'def'
s = s1 + s2
print(s) # 结果:abcdef

但是直接相减 s1-s2是不允许的,那么如何进行字符串相减呢?

比如下面两个问题:

  • 1.输入s1 = ‘abcdefghijk’, s2 = ‘aceac’, 找出s1中不包含s2的所有值
  • 2.已知字符串列表li, 每个元素存放的是用户名、手机号、邮箱号、编程语言。
    如:li = [‘令狐冲 +8618812345678 linghu@163.com Java’, ‘任盈盈 +8617712345678 renying@163.com Python’, ‘风清扬 16612345678’, ‘东方不败 java’]
    要求将元素里:空格' '全替换为分号;+86去掉,@163.com替换为@qq.comJava替换为Python

怎么做?类似这种的怎么找思路?看完下面我写的博文全就会了,慢慢来:

2. 知识点:

replace()用法解释
s.replace(str1, str2)将字符串s中的str1部分, 全替换成str2
s.replace(str1, str2, count)将字符串s中的str1部分, 替换成str2, count表最大替换数量

3. 例题:

输入str1 = ‘abcdefghijk’, str2 = ‘aceac’, 找出s1中不包含s2的所有值

分析:
  • return str1。----- 利用str2搞str1。
  • 注意:str2有重值,故为了提高效率和避免出错,一定要先对str2进行去重处理。
思路:

(1)【核心代码】设计:

  • 法1:replace()替换空格法
  • 法2:[:] 冒号截取法。":"语法实现删除下标为i的元素

(2)【去重】设计:

  • 法1:set()法 ------- 注意:此法去重会打乱原来顺序,视情况而sort()
  • 法2:遍历元素法。----- 最简单的思路,代码思想很重要!但是代码看起来不太高大尚~
代码:

(1) 【去重】:str2去重

str1 = 'abcdefghijk'
str2 = 'aceac'

# 去重(法1):---- set()法
li = list(set(str2)) # ['e', 'c', 'a']这个值是变化的,顺序不一定
li.sort(key=str2.index) # ['a', 'c', 'e']
"""
## 注:
# (1)set()可以去重,但结果不会保持保持原来的顺序。故有时候需要sort()
# (2)li = set(str2) # 结果:{'e', 'c', 'a'} 会改变原顺序。
# (3)set()操作是生成copy(),故不会改变原str2的顺序。
"""

# 去重(法2):------遍历元素法(简单但很重要)
li = []
for c in str2:
    if c not in li:
        li.append(c)


# test
print(li) # ['a', 'c', 'e']

(2) 【核心代码】:删减

# 删减(法1)------ replace()替换空格法
for c in li:
    str1 = str1.replace(c, "")

# 删减(法2)------ 冒号截取法。
for c in li:
    if c in str1:
        str1= str1[:str1.index(c)] + str1[str1.index(c)+1:] # str1.index(c) 是返回c在str1中的下标。如下标是5,这里str1 = str1[:5] + str1[6:]实现了冒号截取再拼接,即:删除了元素str[5]


# test
print(str1) # bdfghijk
注1:有的去重之前可进行排序,视情况而定!

排序:

# 排序
str2 = 'aceac'
li = list(str2) # ['a', 'c', 'e', 'a', 'c']
li = sorted(li) # ['a', 'a', 'c', 'c', 'e']
注2:若没有重值,可直接删减,如:找出s1中不包含s2的所有元素
s1 = 'sfdad'
s2 = 'sfd'
s = s1.replace(s2, "")
print() # 结果 ad

for c in s2:
    if c in s1:
        s1= s1[:s1.index(c)] + s1[s1.index(c)+1:]

4. 补充知识点:

1、strip()
函数功能
strip()去除两端的某字符。如strip(’ '),去除两端空格。 类似php:trim()
lstrip()只删除左端。 类似php:ltrim()
rstrip()只删除右端。 类似php:rtrim()
s1 = 'aaabcdaaa'
s1 = s1.strip('a') # 等价 php中 trim
print(s1) # bcd
s1 = s1.lstrip('a') # 等价 php中 ltrim
print(s1) # bcdaaa
s1 = s1.rstrip('a') # 等价 php中 rtrim
print(s1) # aaabcd
str2 = "   Hello World      ";
str2 = str2.strip() # 去除首尾空格
print str2; # Hello World
2、ord() ----- 仅针对 ‘字符’。即ord(char) 将字符转成ASCII码进行计算
char1 = 'c'
char2 = 'd'
c = ord(char1) - ord(char2)
print(c) #  # 结果:-1
print(ord('d') - ord('c')) # 结果:1

实战(自编)

已知字符串列表li, 每个元素存放的是用户名、手机号、邮箱号、编程语言。
如:li = [‘令狐冲 +8618812345678 linghu@163.com Java’, ‘任盈盈 +8617712345678 renying@163.com Python’, ‘风清扬 16612345678’, ‘东方不败 java’]
要求将元素里:空格' '全替换为分号;+86去掉,@163.com替换为@qq.comJava替换为Python

思路:
  • 先考虑一个string怎么处理;
  • 之后,因为看到字符串列表了,要马上想到用字典,会利用Hash!
代码:
li = ['令狐冲 +8618812345678 linghu@163.com Java', '任盈盈 +8617712345678 renying@163.com Python', '风清扬 16612345678', '东方不败 Java']
dict = {' ' : ';',
        '+86' : '',
        '@163.com' : '@qq.com',
        'Java' : 'Python'
        }

new_li = []
for str in li:
    for key in dict:
        str = str.replace(key, dict[key])
    new_li.append(str)
print(new_li)

运行结果:

['令狐冲;18812345678;linghu@qq.com;Python', '任盈盈;17712345678;renying@qq.com;Python', '风清扬;16612345678', '东方不败;Python']

这个用到的就是上面 问题1(连续型)。若遇到随机+重值型的字符串列表参考上面问题2,原理相同。

附:如何查找一个字符串s1 包含另一个字符串s2?

【思路】:可用 RK(Rabin-Karp)算法。
先对s2求hash;再对s1每个长度为len(s2)的子字符串求hash。用hash比较两个hash是否相等。
参考:https://blog.csdn.net/gengzhikui1992/article/details/105424680

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值