C++实现LeetCode(642.设计搜索自动补全系统)

[LeetCode] 642. Design Search Autocomplete System 设计搜索自动补全系统

Design a search autocomplete system for a search engine. Users may input a sentence (at least one word and end with a special character '#'). For each character they type except '#', you need to return the top 3historical hot sentences that have prefix the same as the part of sentence already typed. Here are the specific rules:

  1. The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before.
  2. The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first).
  3. If less than 3 hot sentences exist, then just return as many as you can.
  4. When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list.

Your job is to implement the following functions:

The constructor function:

AutocompleteSystem(String[] sentences, int[] times): This is the constructor. The input is historical data. Sentences is a string array consists of previously typed sentences. Times is the corresponding times a sentence has been typed. Your system should record these historical data.

Now, the user wants to input a new sentence. The following function will provide the next character the user types:

List<String> input(char c): The input c is the next character typed by the user. The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). Also, the previously typed sentence should be recorded in your system. The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed.

Example:
Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2]) 
The system have already tracked down the following sentences and their corresponding times: 
"i love you" : 5 times 
"island" : 3 times 
"ironman" : 2 times 
"i love leetcode" : 2 times 
Now, the user begins another search: 

Operation: input('i') 
Output: ["i love you", "island","i love leetcode"] 
Explanation: 
There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". Also we only need to output top 3 hot sentences, so "ironman" will be ignored. 

Operation: input(' ') 
Output: ["i love you","i love leetcode"] 
Explanation: 
There are only two sentences that have prefix "i ". 

Operation: input('a') 
Output: [] 
Explanation: 
There are no sentences that have prefix "i a". 

Operation: input('#') 
Output: [] 
Explanation: 
The user finished the input, the sentence "i a" should be saved as a historical sentence in system. And the following input will be counted as a new search. 

Note:

  1. The input sentence will always start with a letter and end with '#', and only one blank space will exist between two words.
  2. The number of complete sentences that to be searched won't exceed 100. The length of each sentence including those in the historical data won't exceed 100.
  3. Please use double-quote instead of single-quote when you write test cases even for a character input.
  4. Please remember to RESET your class variables declared in class AutocompleteSystem, as static/class variables are persisted across multiple test cases. Please see here for more details.

这道题让实现一个简单的搜索自动补全系统,当我们用谷歌或者百度进行搜索时,会有这样的体验,输入些单词,搜索框会弹出一些以你输入为开头的一些完整的句子供你选择,这就是一种搜索自动补全系统。根据题目的要求,补全的句子是按之前出现的频率排列的,高频率的出现在最上面,如果频率相同,就按字母顺序来显示。输入规则是每次输入一个字符,然后返回自动补全的句子,如果遇到井字符,表示完整句子结束。那么肯定需要一个 HashMap,建立句子和其出现频率的映射,还需要一个字符串 data,用来保存之前输入过的字符。在构造函数中,给了一些句子,和其出现的次数,直接将其加入 HashMap,然后 data 初始化为空字符串。在 input 函数中,首先判读输入字符是否为井字符,如果是的话,那么表明当前的 data 字符串已经是一个完整的句子,在 HashMap 中次数加1,并且 data 清空,返回空集。否则的话将当前字符加入 data 字符串中,现在就要找出包含 data 前缀的前三高频句子了,使用优先队列来做,设计的思路是,始终用优先队列保存频率最高的三个句子,应该把频率低的或者是字母顺序大的放在队首,以便随时可以移出队列,所以应该是个最小堆,队列里放句子和其出现频率的 pair 对儿,并且根据其频率大小进行排序,要重写优先队列的 comparator。然后遍历 HashMap 中的所有句子,首先要验证当前 data 字符串是否是其前缀,没啥好的方法,就逐个字符比较,用标识符 matched,初始化为 true,如果发现不匹配,则 matched 标记为 false,并 break 掉。然后判断如果 matched 为 true 的话,说明 data 字符串是前缀,那么就把这个 pair 加入优先队列中,如果此时队列中的元素大于三个,那把队首元素移除,因为是最小堆,所以频率小的句子会被先移除。然后就是将优先队列的元素加到结果 res 中,由于先出队列的是频率小的句子,所以要加到结果 res 的末尾,参见代码如下:

class AutocompleteSystem {
public:
    AutocompleteSystem(vector<string> sentences, vector<int> times) {
        for (int i = 0; i < sentences.size(); ++i) {
            freq[sentences[i]] += times[i];
        }
        data = "";
    }
    vector<string> input(char c) {
        if (c == '#') {
            ++freq[data];
            data = "";
            return {};
        }
        data.push_back(c);
        auto cmp = [](pair<string, int>& a, pair<string, int>& b) {
            return a.second > b.second || (a.second == b.second && a.first < b.first);
        };
        priority_queue<pair<string, int>, vector<pair<string, int>>, decltype(cmp) > q(cmp);
        for (auto f : freq) {
            bool matched = true;
            for (int i = 0; i < data.size(); ++i) {
                if (data[i] != f.first[i]) {
                    matched = false;
                    break;
                }
            }
            if (matched) {
                q.push(f);
                if (q.size() > 3) q.pop();
            }
        }
        vector<string> res(q.size());
        for (int i = q.size() - 1; i >= 0; --i) {
            res[i] = q.top().first; q.pop();
        }
        return res;
    }

private:
    unordered_map<string, int> freq;
    string data;
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/642

类似题目:

Implement Trie (Prefix Tree)

Top K Frequent Words

参考资料:

https://leetcode.com/problems/design-search-autocomplete-system/

https://leetcode.com/problems/design-search-autocomplete-system/discuss/176550/Java-simple-solution-without-using-Trie-(only-use-HashMap-and-PriorityQueue)

https://leetcode.com/problems/design-search-autocomplete-system/discuss/105379/Straight-forward-hash-table-%2B-priority-queue-solution-in-c%2B%2B-no-trie

到此这篇关于C++实现LeetCode(642.设计搜索自动补全系统)的文章就介绍到这了,更多相关C++实现设计搜索自动补全系统内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++实现LeetCode(237.删除链表的节点)

    [LeetCode] 237.Delete Node in a Linked List 删除链表的节点 Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with va

  • C++实现LeetCode(201.数字范围位相与)

    [LeetCode] 201.Bitwise AND of Numbers Range 数字范围位相与 Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive. For example, given the range [5, 7], you should return 4. Credits: Special t

  • C++实现LeetCode(208.实现字典树(前缀树))

    [LeetCode] 208. Implement Trie (Prefix Tree) 实现字典树(前缀树) Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie.insert("apple"); trie.search("apple");   // returns true trie.search("app&

  • C++实现LeetCode(199.二叉树的右侧视图)

    [LeetCode] 199.Binary Tree Right Side View 二叉树的右侧视图 Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. For example: Given the following binary tree,    1     

  • C++实现LeetCode(211.添加和查找单词-数据结构设计)

    [LeetCode] 211.Add and Search Word - Data structure design 添加和查找单词-数据结构设计 Design a data structure that supports the following two operations: void addWord(word) bool search(word) search(word) can search a literal word or a regular expression string c

  • C++实现LeetCode(203.移除链表元素)

    [LeetCode] 203.Remove Linked List Elements 移除链表元素 Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 Return: 1 --> 2 --> 3 --> 4 --> 5 Credits

  • C++实现LeetCode(202.快乐数)

    [LeetCode] 202.Happy Number 快乐数 Write an algorithm to determine if a number is "happy". A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits,

  • C++实现LeetCode(207.课程清单)

    [LeetCode] 207. Course Schedule 课程清单 There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] Given

  • C++实现LeetCode(642.设计搜索自动补全系统)

    [LeetCode] 642. Design Search Autocomplete System 设计搜索自动补全系统 Design a search autocomplete system for a search engine. Users may input a sentence (at least one word and end with a special character '#'). For each character they type except '#', you ne

  • 使用Bootstrap typeahead插件实现搜索框自动补全的方法

    这就是贴代码的坏处之一:搜索框快被网友玩儿坏了!!!有故意输入空格的,有输入or 1=1的,有alert的,有html乱入的.......而且好像还在玩儿,随他们去吧,只要开心就好. 在项目中,经常会用到输入框的自动补全功能,就像百度.淘宝等搜索框一样:当用户输入首字母.关键词时,后台会迅速将与此相关的条目返回并显示到前台,以便用户选择,提升用户体验.当然本项目的补全功能和这些大厂的技术是没有可比性的,但用于站内搜索也是绰绰有余了. 接触到的自动补全插件主要有两个:autocomplete和ty

  • 利用Redis如何实现自动补全功能

    忘了redis从哪个版本开启,能够根据输入的部分命令前缀给出提示,即自动补全.接下来笔者介绍基于redis实现这个很酷的功能. about sorted set 假设结果中有mara,marabel,marcela.现在我们输入mar,就能得到这三个名字,并且输出结果按照字典排序.在实现这个需求之间,我们先简单介绍sorted set. 大家都知道sorted set是按照score排序的: 127.0.0.1:6380> zadd test 85 sida 127.0.0.1:6380> z

  • JQuery搜索框自动补全(模糊匹配)功能实现示例

    本地实现了一个搜索框自动补全的小功能,在JQuery UI的autocomplete插件的基础上,加入了自己的业务代码,贴出来回顾一下,同时可以给大家一个参考 首先贴出的是JQuery Ui 的自动补全插件部分的代码,后面的功能都是在其基础上追加的,直接拷贝到你的本地就可以直观的看到运行效果,也可以到官网上面体验和查看,为了方便,我这里是直接引入的JS链接点击下载JQuery UI的源码 <!doctype html> <html lang="en"> <

  • 搜索历史基本原理实现即时自动补全联想搜索技巧

    目录 实现搜索历史-[即时自动补全&联想搜索] 如何实现基于个人搜索历史的联想推荐 架构图 词汇表实现 实现原理 新增关键字操作 删除关键字操作 查询推荐列表操作 实现搜索历史-[即时自动补全&联想搜索] 无论是新闻.内容.还是电商平台,联想输入已经成为搜索功能的标配,早已不是什么新鲜事物.我们随便打开一个搜索引擎或者是电商平台,当我们在输入框输入拼音或者文字时就会看到输入框下方弹出有意义的搜索建议,提示我们是不是想要输入“以下”内容,帮助我们补齐输入或是修正错误的输入,优化我们的搜索体验

  • PHP自动补全表单的两种方法

    效果图: 第一种:从数据库中检索之后补全 第二种:邮箱等纯前端的补全 先说第二种,使用开源的插件,所以相对简单. github上面的项目 completer. https://github.com/fengyuanchen/completer 做法特别容易,github上面有详细的文档. 一开始尝试用这个来配上自己的后台代码,做成第一种的自动补全,搞了半天失败了.可能本人js太差,改动太多的话,代码很复杂,除非认真研究上面这个开源项目. 主要失败在我在后台数据库找出来的完整的模糊查询得到的数据,

  • JSP + ajax实现输入框自动补全功能 实例代码

    下面是我用ajax实现的输入框自动补全功能,数据库数据很少,大体模仿出了百度首页的提示功能,当然,人家百度的东西不只是这么简单的!先看运行效果: index.jsp(包含主要的js代码) 复制代码 代码如下: <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath();

  • 基于jquery实现的自动补全功能

    本文实例讲述了基于jquery实现的自动补全功能的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: $(function() {     // 自动补全     var maxcount = 0;// 表示他最大的值     var thisCount =0;// 初始化他框的位置     $("body").prepend("<div style='width:120px; display:none; background:#FFFFFF; pos

  • 详解jQuery UI库中文本输入自动补全功能的用法

    自动补全(autocomplete),是一个可以减少用户输入完整信息的UI 工具.一般在 输入邮箱.搜索关键字等,然后提取出相应完整字符串供用户选择. 一.调用autocomplete()方法 $('#email').autocomplete({ source : ['aaa@163.com', 'bbb@163.com', 'ccc@163.com'], }); 二.修改autocomplete()样式    由于autocomplete()方法是弹窗,然后鼠标悬停的样式.通过Firebug

  • Android 自动补全提示输入AutoCompleteTextView、 MultiAutoCompleteTextView

    以在搜索框搜索时,自动补全为例: 其中还涉及到一个词,Tokenizer:分词器,分解器. 上效果图: MainActivity.java: package com.joan.testautocomletetextview; import android.R.array; import android.os.Bundle; import android.app.Activity; import android.content.res.Resources; import android.view.

随机推荐