洛谷P1026&NOIP2001 统计单词个数

本文介绍了一种使用动态规划解决字符串划分问题的方法。通过预处理数组记录子串中不同单词的数量,利用DP状态转移方程求解最优解。适用于需要高效处理大量字符串数据的应用场景。

刚看到这个题一直在纠结怎么划分成k份再转移,事实证明我想多了

先预处理出数组w[I][j],表示从i到j的单词个数,如果有多个以i开头的单词,只统计一次即可

dp[I][j]表示从0到i划分成j份,则

dp[I][j]=max(dp[k][j-1]+w[k+1][j]|j-1<=k<i)

顺便%一下用贪心A掉此题的ZY大神


#include<iostream>
#include<cstring>
#include<string>
#define f dp
#define maxn 200+2
#define maxk 40+2
#define maxs 6+2 
using namespace std;
string dic[maxs],a;
int p,k,s,dp[maxn][maxk];//表示从0到i分成j份 
int w[maxn][maxn];//表示从i到j有w[i][j]个单词 
void init(void){
	cin>>p>>k;
	string temp;
	a+='0';
	for(int i=0;i<p;i++){
		cin>>temp;
		a+=temp;
	}
	cin>>s;
	for(int i=1;i<=s;i++)
		cin>>dic[i];
	memset(dp,0,sizeof(dp));
	memset(w,0,sizeof(w));
	for(int i=p*20;i>0;i--){
		for(int j=i;j<=p*20;j++){//枚举字符 
			for(int k0=1;k0<=s;k0++){//枚举单词 	
				if(a.find(dic[k0],i)==i&&dic[k0].length()<=j-i+1){
					w[i][j]++;
					break;
				}
			}
			w[i][j]+=w[i+1][j];
		}
	}
	/*for(int i=1;i<=p*20;i++){
		dp[i][i]=
	}*/
	return;
}
int main(){
	init();
	//dp[i][j]=max(dp[k][j-1]+w[k+1]|k>=j-1) 
	for(int i=1;i<=p*20;i++){
		for(int j=1;j<=i&&j<=k;j++){
			int temp=0;
			for(int k0=j-1;k0<i;k0++)
				temp=max(temp,dp[k0][j-1]+w[k0+1][i]);
			dp[i][j]=temp;
		}
	}
	cout<<dp[p*20][k];
	return 0;
} 


### 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]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值