pangram(字母全称句):判断句子是否为回文句,涉及的是对句子中的字母进行处理,判断一个句子是否包含了所有的字母
1. 使用集合(Set)实现(最推荐的方式)
def is_pangram(sentence):
sentence = sentence.lower() # 转换为小写,确保大小写不敏感
set1 = set() # 使用集合
for char in sentence:
if char.isalpha(): # 如果字符是字母
set1.add(char) # 将字母添加到集合
return len(set1) == 26 # 判断集合中是否包含所有26个字母
优点:
- 效率高:集合具有自动去重的功能,操作简单且时间复杂度为
O(n)
,其中n
是句子的长度。 - 简洁性强:代码简单易懂,使用集合可以直接存储不重复的字母。
缺点:
- 对于一些特殊字符(如标点符号),仍然需要检查并过滤掉。
2. 使用 set
和 filter()
函数实现
def is_pangram(sentence):
sentence = sentence.lower()
return len(set(filter(str.isalpha, sentence))) == 26
优点:
- 简洁:使用
filter()
函数过滤掉所有非字母字符,减少了for
循环的使用。 - 清晰:利用
filter
和str.isalpha
来过滤非字母字符,并使用集合自动去重。
缺点:
- 代码可能对于不熟悉
filter
函数的开发者较难理解,虽然简洁,但可读性略差。
3. 使用 collections.Counter
来计数
from collections import Counter
def is_pangram(sentence):
sentence = sentence.lower()
counts = Counter(char for char in sentence if char.isalpha())
return len(counts) == 26
优点:
Counter
会统计每个字母出现的次数,如果只关心字母是否出现,Counter
是一个很有用的工具。- 灵活:可以很容易地修改以获取更多统计信息(比如每个字母的出现次数)。
缺点:
- 可能稍微有点重,因为
Counter
的实现比直接用集合要多一些开销。 - 你可能不需要统计字母的频率,只是检查是否包含所有字母,使用
Counter
比直接使用集合要多余一些。
4. 使用列表(List)来存储字母
def is_pangram(sentence):
sentence = sentence.lower()
alphabet = [False] * 26
for char in sentence:
if char.isalpha():
index = ord(char) - ord('a') # 计算字母对应的索引
alphabet[index] = True # 标记该字母出现过
return all(alphabet) # 如果所有字母都出现过,则返回 True
优点:
- 效率高:使用一个固定大小的列表来标记字母是否出现,空间复杂度为
O(1)
。 - 无额外库依赖:纯 Python 实现,不依赖额外的库,如
set
或collections.Counter
。
缺点:
- 代码稍显复杂:相较于使用集合,使用列表的方式稍显繁琐,需要自己计算字母的索引,并通过
ord
函数转换。 - 代码不够简洁:相比其他方法,写法可能较为冗长,尤其是对于初学者。
5. 使用正则表达式(Regex)
import re
def is_pangram(sentence):
sentence = sentence.lower()
return len(set(re.findall(r'[a-z]', sentence))) == 26
优点:
- 强大:正则表达式非常强大,能够灵活匹配字符。
- 简洁:代码简洁,直接使用正则表达式匹配所有字母字符。
缺点:
- 性能较差:正则表达式的性能相对较差,尤其是在处理大文本时可能不如其他方法高效。
- 可读性较差:对于不熟悉正则表达式的开发者,代码的可读性较差,可能需要花时间理解。
6. 使用 str.count()
方法
def is_pangram(sentence):
sentence = sentence.lower()
return all(sentence.count(chr(i)) > 0 for i in range(ord('a'), ord('z') + 1))
优点:
- 直观:对于每个字母,直接检查其在字符串中的出现次数,语法直观,易于理解。
缺点:
- 性能低:对于每个字母都需要遍历一次字符串,导致时间复杂度是
O(26*n)
,即 O(n),虽然是线性时间复杂度,但会比直接使用集合方法慢一些。
总结与比较:
方法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
---|---|---|---|---|
集合(Set)实现 | O(n) | O(1) | 高效简洁,自动去重 | 对特殊字符需要检查 |
filter() + 集合实现 |
O(n) | O(1) | 简洁,高效 | 可读性差,特别是对不熟悉 filter 的开发者 |
Counter 计数器 |
O(n) | O(1) | 灵活,可以获取字母频率 | 有些冗余,性能稍差 |
列表实现 | O(n) | O(1) | 高效,无外部依赖 | 代码相对繁琐 |
正则表达式 | O(n) | O(1) | 简洁,强大 | 性能较差,可读性差 |
str.count() 方法 |
O(26n) | O(1) | 直观易懂 | 性能较差,效率较低 |
推荐:
- 性能最佳:如果需要处理大数据量,建议使用集合(Set)实现或列表实现,因为它们时间复杂度较低且直接操作字母。
- 简洁性优先:如果追求代码简洁,使用
filter()
或re.findall()
结合集合也非常有效。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)