查找舆情热词算法题-C++实现

前言

本文记录4月6日晚7点一场软件开发岗笔试的题目,思路以及代码实现。

一、题目简介

题目:
查找舆情热词
具体描述:
输入正整数topN和文章数M,正整数topN表示要找出来的出现频率最高的topN个字符串,M篇文章中每篇文章会有两个字符串,一个是标题字符串,一个是正文字符串,字符串间有空格,每个单词被空格隔开。我们的目的就是把这M篇文章连标题带正文拆成一个个单词,然后统计这一堆单词出现频率最高的topN个。
统计规则:标题中出现的词语频率系数为3,正文中出现的词语频率系数为1,返回的答案应该按照词语出现从高到低排序,当词语出现次数频率相同时,在标题中出现频率次数高的排在前面,如果仍然相同,则按照词语在标题中出现的先后顺序进行排序,如果仍相同,则按照词语在正文中出现的先后顺序进行排序,先出现的排在前面。
输入输出:
输入:第一行输入为正整数topN和文章数M。然后由于每篇文章有标题和正文两行,因此后面有2*M行数据。从第二行起,按顺序处理每篇文章的标题串和正文串。
输出:出现频率topN高的单词,每个单词用‘ ’隔开。

二、思路

求topK,常用思路就是用堆实现,本题由于要统计次数和出现顺序因此还要用一大堆哈希表,对于这个问题,本人首先想到使用小根堆实现,先把这几个哈希表弄好,然后维护一个容量不超过topN的小根堆,堆中存放着出现频率topN的单词,堆顶元素即为出现频率排第N位的单词,从total_fre这个大哈希表里依次取单词往堆里压,每次判断新单词和堆顶元素的出现频率大小关系,若新单词出现频率大于堆顶元素则弹出堆顶元素并将这个元素压入堆,否则堆不变,最后将堆中元素依次弹出再反转一下就是出现次数从高到低的topN个元素啦。(这是我最初想到的一种空间复杂度相对理想的完美思路)

但是!由于本题中出现频率的比较规则过于复杂,在给堆定义了cmp后还得再写函数去比较新单词和堆顶元素的出现频率大小关系什么的,这非常麻烦,而且仔细思考后发现和这么多哈希表相比这小根堆其实省不了多少空间,干脆用大根堆,新单词来了也不用判断啥了,直接压进去就完事,最后弹topN次就行了。

三、C++代码实现

#include <iostream>
#include <cstring>
#include <unordered_map>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
int topn, m;
unordered_map<string, int> total_fre;  // 维护每个单词在标题和正文中的出现总次数(已按(3,1)加权)
unordered_map<string, int> title_fre;  // 维护每个单词在标题中的出现次数
unordered_map<string, int> first_in_title;  // 维护每个单词在标题中首次出现的位置
unordered_map<string, int> first_in_text;  // 维护每个单词在正文中首次出现的位置

struct cmp
{
    bool operator()(pair<string, int> &p1, pair<string, int> &p2)
    {
        // 比较规则0:比单词在标题和正文中出现的总次数
        if (p1.second != p2.second) return p1.second < p2.second;
        // 比较规则1:比单词在标题中出现的次数
        else if (title_fre[p1.first] != title_fre[p2.first])
            return title_fre[p1.first] < title_fre[p2.first];
        // 比较规则2:比单词在标题中出现的顺序
        else if (first_in_title[p1.first] != first_in_title[p2.first])
            return first_in_title[p1.first] < first_in_title[p2.first];
        // 比较规则3:比单词在正文中出现的顺序
        else
            return first_in_text[p1.first] < first_in_text[p2.first];
    }
};

priority_queue<pair<string, int>, vector<pair<string, int>>, cmp> pq; // 自定义大根堆,用于存储所有pair<string, int>

int main()
{
    cin >> topn >> m;  // 输入正整数topN和文章数M
    string lineStr;
    getline(cin, lineStr);  // 换行
    while (m--)
    {
        string title, text;
        getline(cin, title); // 输入标题
        for (int i = 0, j = 0, index = INT32_MAX; i <= title.size(); i++)
        {
            if (i == title.size() || title[i] == ' ')
            {
                string str = title.substr(j, i - j);
                j = i + 1;
                total_fre[str] += 3;
                title_fre[str] += 1;
                if (first_in_title.count(str) == 0)
                    first_in_title[str] = index--;
            }
            else continue;
        }
        getline(cin, text); // 输入正文
        for (int i = 0, j = 0, index = INT32_MAX; i <= text.size(); i++)
        {
            if (i == text.size() || text[i] == ' ')
            {
                string str = text.substr(j, i - j);
                j = i + 1;
                total_fre[str] += 1;
                if (first_in_text.count(str) == 0)
                    first_in_text[str] = index--;
            }
            else continue;
        }
    }
    for (auto it = total_fre.begin(); it != total_fre.end(); it++)
    {
        pq.push(pair<string, int>{it->first, it->second});  // 所有单词压入大根堆,直接pop就是按序输出
    }
    while (topn--)
    {
        cout << pq.top().first << ' ';
        pq.pop();
    }
    return 0;
}

总结

菜鸡变成卷王的第一步!

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
舆情反转预测研究是指通过对舆情事件的演化分析,结合改进的KE-SMOTE算法,进行舆情的反转预测。舆情反转预测是指对于一个正在发展的舆情事件,通过分析事件的演化趋势,预测舆情的发展方向是否会发生反转。 首先,对于舆情事件的演化分析是基于历史数据和事件的现状进行的。可以通过监测社交媒体、新闻报道、用户评论等方式收集事件相关的信息。通过对事件的演化过程进行分析,可以了解事件的起因和发展趋势,并且找出可能导致舆情反转的关键因素。 其次,为了提高舆情反转预测的准确性,可以采用改进的KE-SMOTE算法。KE-SMOTE是一种基于少数类样本增强的算法,可以通过合成新的少数类样本来平衡数据集的不平衡。改进的KE-SMOTE算法在原有算法的基础上,考虑了关键因素对数据样本的影响程度,并根据影响程度调整新合成样本的数量和属性。通过这种方式,可以提高算法对重要因素的关注程度,从而提高舆情反转预测的准确性。 最后,基于舆情事件演化分析和改进的KE-SMOTE算法,可以进行舆情反转预测。在实际应用中,可以将收集到的舆情事件数据进行预处理和特征提取,然后使用改进的KE-SMOTE算法进行训练和预测。通过对模型的评估和优化,可以得到更准确的舆情反转预测结果。 综上所述,基于舆情事件演化分析和改进的KE-SMOTE算法舆情反转预测研究,可以从分析事件演化趋势和平衡数据集的角度,提高舆情反转预测的准确性,为舆情管理提供更有效的决策支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值