PAT 06-3. 单词长度

该程序旨在读取一串包含多个单词的文本,单词由空格分隔,以'.'结束。程序需输出每个单词的长度,包括特殊字符如'it's'。连续的空格和结束的'.'不计入单词长度。输入和输出皆为一行,单词长度用空格隔开。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

你的程序要读入一行文本,其中以空格分隔为若干个单词,以‘.’结束。你要输出每个单词的长度。这里的单词与语言无关,可以包括各种符号,比如“it’s”算一个单词,长度为4。注意,行中可能出现连续的空格;最后的‘.’不计算在内。

输入格式:

<think>好的,用户需要编写一个Python程序来统计英文文本中的不同单词数量,并输出词频最高的前10%的单词。首先,我需要明确用户的具体需求。用户提到要考虑单词的定义规则:大小写不敏感、最长15个字符、仅包含字母数字和下划线。这意味着在预处理时,需要将单词统一转换为小写或大写,截断超过15个字符的部分,并且过滤掉不符合字符要求的单词。 接下来,我需要考虑如何处理输入的文本。用户可能提供的是文件路径或者直接输入的文本,但根据问题描述,可能假设输入是一段给定的英文文本。使用Python的字符串处理功能会比较方便。 步骤分解: 1. **文本预处理**:首先需要将文本中的标点符号去除,或者根据分隔符拆分单词。用户提到单词由空格或标点(逗号、句号)分隔,但需要注意可能存在其他标点的情况。可能需要使用正则表达式来分割单词。 2. **单词规范化**:将所有单词转换为小写,以保证大小写不敏感。同时检查每个单词是否符合仅包含字母、数字和下划线的要求,并且长度不超过15个字符。如果超过,截断到15个字符。 3. **统计词频**:使用字典来记录每个单词出现的次数。遍历处理后的单词列表,更新字典中的计数。 4. **排序和筛选前10%**:计算总共有多少个不同的单词,然后确定前10%的数量。例如,如果有1000个不同单词,前10%就是100个。然后根据词频排序,选出最高的部分。 需要注意的细节: - 正则表达式的模式可能需要调整,确保正确分割单词。例如,使用`r&#39;\b[\w]{1,15}\b&#39;`来匹配长度1到15的单词,但可能需要更精确的处理,比如先分割再过滤。 - 截断单词时,如果原单词超过15个字符,取前15个。例如,"abcdefghijklmnopqrst"变成"abcdefghijklmno"。 - 处理标点时,可能需要将非字母数字下划线的字符视为分隔符,或者在分割时忽略这些字符。 可能的代码结构: 1. 读取输入文本。 2. 使用正则表达式分割单词,同时转换为小写。 3. 过滤无效单词(如空字符串)并截断长度。 4. 统计词频。 5. 排序词频字典,计算前10%的数量。 6. 输出结果。 测试案例:例如输入文本包含重复单词,混合大小写,超长单词,特殊字符等,验证程序是否正确处理。 潜在问题: - 如何定义单词的分割符?用户提到空格、逗号、句号,但其他标点可能也需要处理,比如分号、感叹号等。使用正则表达式`r&#39;[^a-zA-Z0-9_]+&#39;`来分割可能更全面。 - 处理像连字符的情况,例如"state-of-the-art"是否视为一个单词?根据用户的需求,可能需要分割成多个单词,但用户要求仅包含字母数字和下划线,因此连字符会被视为分隔符,分割成多个部分。 - 统计前10%时,如果不同单词数量不足10个,如何处理?可能需要向上取整,例如使用`math.ceil`。 代码示例: ```python import re from collections import defaultdict def process_text(text): # 分割单词并处理 words = re.findall(r&#39;\b[\w]{1,15}\b&#39;, text.lower()) valid_words = [word[:15] for word in words if word.isalnum() and &#39;_&#39; not in word] # 这里可能需要调整正则表达式和过滤条件,比如允许下划线 # 修正:用户允许包含下划线,所以应该允许单词包含下划线,但排除其他符号 # 重新分割,使用正则表达式匹配字母、数字和下划线组成的单词 words = re.findall(r&#39;\b[a-zA-Z0-9_]{1,15}\b&#39;, text.lower()) return words text = "Given some text, with words like Python3, hello_world, and someLongWordThatIsTooLong." processed = process_text(text) # 统计 word_counts = defaultdict(int) for word in processed: word_counts[word] +=1 sorted_words = sorted(word_counts.items(), key=lambda x: (-x[1], x[0])) total_unique = len(sorted_words) top_10_percent = sorted_words[: (total_unique +9)//10] print(f"不同单词数量: {total_unique}") print("前10%的单词:", top_10_percent) ``` 需要检查正则表达式是否正确,是否遗漏了某些情况,比如下划线的处理。例如,原问题中的单词可能包含下划线,所以正则表达式应包含`[a-zA-Z0-9_]`,即`\w`因为\w在Python的re模块中确实包括下划线。但需要注意,`\b`是单词边界,可能无法正确匹配以下划线开头的单词,比如"_test"。因此可能需要调整正则表达式,允许单词以字母开头,包含下划线和数字。或者用户是否允许以下划线开头的单词?问题描述中没有明确,但根据一般情况,可能允许。因此,可能需要调整正则表达式为`r&#39;(?<!\S)[a-zA-Z0-9_]{1,15}(?!\S)&#39;`或者其他方式,确保正确分割。 或者,更简单的方式是使用split来分割所有非单词字符,然后用列表推导处理每个部分。例如: ```python words = re.split(r&#39;[^\w]+&#39;, text.lower()) words = [word[:15] for word in words if word] ``` 但这样可能会将空字符串包含进来,需要过滤掉。 然后,统计每个符合要求的单词。 在代码中需要确保处理后的单词只包含字母、数字和下划线,并且长度不超过15。例如,如果用户输入的单词有其他字符,比如"hello-world",会被分割成"hello"和"world",如果使用split方法,而如果用正则表达式匹配的话,可能不会包括中间的连字符。 因此,正确的做法是使用正则表达式来匹配符合要求的单词,即由字母、数字、下划线组成,长度1-15。这样,所有不符合的字符都会被排除,或被作为分隔符处理。 所以,正确的正则表达式应为:`r&#39;\b[a-zA-Z0-9_]+\b&#39;`,但需要限制长度1-15。可以调整为`r&#39;\b[a-zA-Z0-9_]{1,15}\b&#39;`,然后转换为小写。 这样,所有匹配的单词都会被提取,并且长度不超过15,字符符合要求。 测试用例: 输入文本:"Hello! This is a test. Test_test 1234, abcdefghijklmnopqrstuvwxyz" 处理后的单词应为:[&#39;hello&#39;, &#39;this&#39;, &#39;is&#39;, &#39;a&#39;, &#39;test&#39;, &#39;test_test&#39;, &#39;1234&#39;, &#39;abcdefghijklmno&#39;](最后一个单词截断到15字符) 统计结果:每个单词出现一次,总共有8个不同单词,前10%是1个(8*0.1=0.8,向上取整为1)。 这样代码就能正确统计。 综上,步骤应该是: 1. 使用正则表达式提取所有符合要求的单词(字母、数字、下划线,1-15长度)。 2. 转换为小写。 3. 统计频率。 4. 排序,取前10%(向上取整)。</think>要编写一个Python程序实现英文文本词频统计,可按照以下步骤实现: ### 实现步骤 1. **文本预处理** - 使用正则表达式`r&#39;(?i)\b[a-z0-9_]{1,15}\b&#39;`匹配最长15字符的单词[^2] - 将所有匹配结果转换为小写 - 过滤空字符串和非法字符 2. **词频统计** ```python from collections import Counter words = re.findall(r&#39;\b[a-z0-9_]{1,15}\b&#39;, text.lower()) word_counts = Counter(words) ``` 3. **结果排序与筛选** ```python sorted_words = sorted(word_counts.items(), key=lambda x: (-x[1], x[0])) top_count = math.ceil(len(sorted_words) * 0.1) ``` ### 完整代码实现 ```python import re import math from collections import Counter def word_frequency_analysis(text): # 提取符合要求的单词 words = re.findall(r&#39;(?i)\b[a-z0-9_]{1,15}\b&#39;, text) words = [w.lower() for w in words] # 统计词频 counter = Counter(words) unique_count = len(counter) # 计算前10% sorted_words = sorted(counter.items(), key=lambda x: (-x[1], x[0])) top_n = math.ceil(unique_count * 0.1) return unique_count, sorted_words[:top_n] # 示例使用 text = "Hello hello_world! This is a test. Test 1234, abcdefghijklmnopqrstuvwxyz" count, top_words = word_frequency_analysis(text) print(f"不同单词数量: {count}") print("词频前10%:", top_words) ``` ### 关键特性说明 1. **正则表达式**:`\b`标记单词边界,`[a-z0-9_]`匹配允许字符,`{1,15}`限制长度 2. **大小写处理**:统一转换为小写保证统计准确性 3. **排序规则**:按词频降序、字母升序排列 4. **边界处理**:使用`math.ceil`确保至少选取1个单词
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值