jmu数据结构实验四任务

本文介绍如何使用C++实现一个程序,统计用户输入英文文章中不同单词的出现次数,并按出现次数和字母顺序进行输出。涉及数据结构如map和结构体数组,以及排序算法。

jmu数据结构实验四任务

选做:题目 4—统计单词的出现次数并输出

总时间限制: 2000ms    内存限制: 4096kB

描述

根据用户给定的一篇包含若干个单词的英文文章(文章只包含英文字母和空格、回车换行符,单词之间

以空格或者回车换行符分隔,单词最短一个字母,最长100个字母;最多包含100000个不同的单词),请

解析出所有不同的单词,并统计出每个单词出现的次数,然后按照单词出现的次数从小到大输出,如果出

现次数一样,则按照英文单词的词典顺序输出(忽略大小写区别,输出时全部变成小写字母)。

输入

英文文章。以“***”作为结束标志。

输出

单词按照出现次数从小到大的输出,一行一个单词。

样例输入

This is just a test
test test te
st
***

样例输出

a
is
just
st
te
this
test

题解

使用 map<string, int> dict 存放每个单词与其对应的存放次数。其中 key 值为单词,value 值为单词出现次数,每次输入使用transform函数(或自己编写转化小写的函数)将单词转化为小写,存入dict。

使用正向迭代器遍历dict,将所有单词及其出现个数存入结构体数组words,之后使用sort函数对结构体数组words进行按出现个数从小到大排序。

代码

#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
using namespace std;
struct word
{
	char word[105];
	int n;
}words[100005];//保存所有单词及其出现个数用于排序
bool cmp(struct word word1, struct word word2)
{
	return word1.n < word2.n;
}
map<string, int> dict;//保存所有单词出现个数
int main()
{
	string word;
	do
	{
		cin >> word;
		if (word != "***")
		{
			transform(word.cbegin(), word.cend(), word.begin(), ::tolower);//利用transfor函数将word转换为小写
			dict[word]++;//单词个数加一
		}
	} while (word != "***");
	auto it = dict.begin();//dict的正向迭代器,用于遍历dict
	int n = 0;//所有单词种数 
	while (it != dict.end())
	{
		memcpy(words[n].word, it->first.c_str(), 105);//将word转换为c风格字符串复制给words[n].word
		words[n].n = it->second;//将该单词出现个数赋值给words[n].n
		it++;//迭代器移动
		n++; //单词种数
	}
	sort(words, words + n, cmp);//对结构体word按单词出现个数从小到大排序
	for (int i = 0; i < n; i++)
	{
		cout << words[i].word << endl;
	}
	return 0;
}

 

### 关于JMU-DS平台中区间删除数据的解题方法 在处理涉及线性表的操作时,尤其是像PTA这样的编程平台上遇到的数据结构操作问题,理解如何高效地执行特定范围内的元素删除至关重要。对于区间删除这类操作,通常涉及到遍历列表找到起始位置和结束位置,并安全移除这些位置之间的所有节点。 针对JMU-DS平台中的具体实现方式,可以考虑如下策略: #### 使用顺序存储结构(数组) 当采用数组作为底层存储机制来表示线性表时,可以通过调整索引来模拟区间的删除过程[^1]。假设有一个整数类型的向量`vec`用于保存一系列数值,为了从该序列中去除指定下标[start, end]之间(含边界)的所有元素,可采取以下C++代码片段展示的方法: ```cpp #include <iostream> #include <vector> using namespace std; void removeRange(vector<int>& vec, int start, int end) { if (start >= 0 && end < vec.size() && start <= end){ // 删除[start,end]闭合区间内的元素 vec.erase(vec.begin()+start, vec.begin()+end+1); } } int main(){ vector<int> data = {1,2,3,4,5}; cout << "原始数据:" ; for(auto& num :data )cout<<num<<" "; removeRange(data ,1,3); // 移除第二个到第个元素 cout<<"\n修改后的数据:"; for(auto &num:data )cout<<num<<" "; return 0; } ``` 此段程序展示了如何通过调用STL容器提供的成员函数`erase()`来进行批量删除。需要注意的是,在实际应用过程中应当先验证输入参数的有效性和合法性,防止越界访问等问题的发生。 #### 链式存储结构下的区间删除 如果选择了链表这种动态分配内存的方式来构建线性表,则需要更加谨慎地管理指针关系以避免造成悬空指针或者循环引用的情况发生。下面给出了一种基于单项链表设计的思想框架,适用于解决类似的需求: 1. 创建两个辅助指针分别指向待删除区域前驱结点(`prev`)以及首地址(`currStart`); 2. 循环迭代直至定位至目标子串头部; 3. 继续前进直到触及尾部标记(`currEnd`); 4. 修改前后连接关系使原中间部分被跳过; 5. 清理不再使用的空间资源; 这种方法虽然逻辑稍显复杂,但在某些场景下可能更为灵活有效。不过值得注意的是,上述两种方案都依赖具体的上下文环境而定,因此建议根据实际情况选择最合适的算法和技术路线。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值