洛谷 P1026 [NOIP2001 提高组] 统计单词个数

本文介绍了一种使用动态规划解决字符串分割问题的方法,目标是通过分割字符串并匹配字典中的单词来最大化单词的数量。文章提供了详细的算法实现步骤,并附带完整的Java代码示例。

题目描述
给出一个长度不超过 200 的由小写英文字母组成的字母串(该字串以每行 20 个字母的方式输入,且保证每行一定为 20 个)。要求将此字母串分成 k 份,且每份中包含的单词个数加起来总数最大。

每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串 this 中可包含 this 和 is,选用 this 之后就不能包含 th。

单词在给出的一个不超过 6 个单词的字典中。

要求输出最大的个数。

输入格式
每组的第一行有两个正整数 p,k。 p 表示字串的行数,k 表示分为 k 个部分。

接下来的 p 行,每行均有 20 个字符。

再接下来有一个正整数 s,表示字典中单词个数。 接下来的 s 行,每行均有一个单词。

输出格式
1个整数,分别对应每组测试数据的相应结果。

在这里插入图片描述
思路:dp。我们用dp[i][j]表示字符串i位置分成j块所包含的单词数量,那么,状态转移方程为:dp[i][j] = dp[u][j-1]+sum[u+1][i]。其中u为小于i的断点,sum[i][j]表示i位置到j位置包含的单词数量。我们可以先预处理出来。根据题意,在处理sum的时候我们可以倒序处理。

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int p = sc.nextInt();
        int k = sc.nextInt();
        String str = "";
        for(int i=0;i<p;i++){
            String t = sc.next();
            str += t;
        }
        int len = str.length();
        int s = sc.nextInt();
        String[] arr = new String[s+5];
        for(int i=0;i<s;i++) arr[i] = sc.next();
        int[][]dp = new int[300][50];//dp[i][j]表示i位置分成j块所包含的最大单词数量 dp[i][j] = dp[u][j-1] + sum[u+1][i]
        int[][] sum = new int[300][300]; //sum[i][j]表示i到j包含的单词数量
        for(int i=len-1;i>=0;i--){
            for(int j=i;j>=0;j--){
                sum[j][i] = sum[j+1][i];
                String temp = str.substring(j,i+1);
                for(int q=0;q<s;q++){
                    if(temp.indexOf(arr[q])==0){
                        sum[j][i]++;
                        break;
                    }
                }
            }
        }
        for(int i=0;i<len;i++){
            dp[i][1] = sum[0][i];
            for(int u=0;u<i;u++)
            for(int j=2;j<=k&&j<=u+1;j++){
                dp[i][j] = Math.max(dp[i][j],dp[u][j-1]+sum[u+1][i]);
            }
        }
        System.out.println(dp[len-1][k]);
    }
}
### Python 实现统计单词个数 要实现统计单词个数的功能,可以通过读取文本文件并逐行处理内容来完成。以下是基于引用的内容以及扩展的知识所提供的解决方案。 #### 解决方案描述 为了满足题目需求,程序需具备以下功能: 1. **读取输入数据**:从标准输入或指定文件中获取待分析的文本。 2. **预处理文本**:将文本转换为统一的小写形式,并去除多余的空白符以便于后续操作[^1]。 3. **分割单词**:通过空格或其他分隔符分离出单个单词。 4. **统计单词频率**:利用 `collections.Counter` 或字典结构记录每个单词出现的次数。 5. **输出结果**:按照要求格式化输出单词及其对应频次。 下面是一个完整的 Python 代码示例: ```python import re from collections import Counter def count_words(text, target_word=None): # 将所有字母转为小写以忽略大小写的差异 text = text.lower() # 使用正则表达式提取单词,过滤掉非字母字符 words = re.findall(r'\b\w+\b', text) # 如果目标单词为空,则计算整个文档的词频分布 word_counts = Counter(words) if target_word is None: result = dict(word_counts.most_common()) else: # 转为目标单词小写版本用于比较 target_word = target_word.lower() result = {target_word: word_counts[target_word]} return result if __name__ == "__main__": input_text = """ This is a sample text with several words. The task involves counting the occurrences of each distinct word, ignoring case and punctuation marks such as commas or periods. """ # 假设用户希望查询某个特定单词 specific_word = "word" output = count_words(input_text, specific_word) print(f"Word '{specific_word}' appears {output[specific_word]} times.") # 查询整体词频分布 all_word_frequencies = count_words(input_text) print("Overall Word Frequencies:") for word, freq in all_word_frequencies.items(): print(f"{word}: {freq}") ``` 上述代码实现了两个主要功能:一是单独统计一个单词在文本中的出现次数;二是返回整个文本中各单词的频率表[^2]。 #### 关键技术点解析 - **字符串标准化**:通过 `.lower()` 方法使大写字母变为小写,从而简化匹配逻辑。 - **正则表达式应用**:借助 `re.findall('\b\w+\b')` 提取出合法的英语单词序列[^3]。 - **高效计数工具**:采用 `Counter` 类型自动汇总重复项的数量,减少手动维护哈希表的工作量[^4]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值