hiho一下~week_2:从简单匹配—>hash—>trie树

题目意思:
对于每一个给出的字符串,都在一个给定的词典里面找到以这个字符串开头的所有单词个数”。
输入
输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词,单词由不超过10个的小写英文字母组成,可能存在相同的单词,此时应将其视作不同的单词。接下来的一行为一个正整数m,表示小Hi询问的次数,其后m行,每一行一个字符串,该字符串由不超过10个的小写英文字母组成,表示小Hi的一个询问。
输出
对于小Hi的每一个询问,输出一个整数Ans,表示词典中以小Hi给出的字符串为前缀的单词的个数。

样例输入
5
babaab
babbbaaaa
abba
aaaaabaa
babaababb
5
babb
baabaaa
bab
bb
bbabbaab
样例输出
1
0
3
0
0

题目分析:
方法一、直接暴力匹配,时间复杂度O(n*m)。
方法二、利用hash时间复杂度,记录每个字符串的前缀的个数,直接进行查找,时间复杂度O(len*n),len是字符串的长度。
方法三、trie树,建树的时间复杂度是O(len*n),查询的时间复杂度是O(len)。

方法二代码(TL):

//方法二hash
void showHash(){
    map<string,int> cnt;
    string s;
    int n,m;
    while(cin>>n){
        cnt.clear();
        for(int i=0;i<n;i++){
            cin>>s;
            string ss="";
            for(int i=0;i<s.size();i++){
                ss+=s[i];
                cnt[ss]++;//记录每一个前缀的出现次数
            }
        }
        cin>>m;
        for(int i=0;i<m;i++){
            cin>>s;
            cout<<cnt[s]<<endl;
        }
    }
}

trie树代码:

/**
 *Author: xiaoran
 *Solution:trie树
 *
 */
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<time.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<fstream>
#define LL long long
using namespace std;
const int MAXN=1000005;

typedef struct Trie_node
{
    int cnt;                    // 统计单词前缀出现的次数
    struct Trie_node* next[26];   // 指向各个子树的指针
    bool exist;                   // 标记该结点处是否构成单词
}TrieNode , *Trie;
//其中next是一个指针数组,存放着指向各个孩子结点的指针。

TrieNode * createTrieNode(){//创建一个新的结点
    TrieNode * node = (TrieNode *) malloc(sizeof(TrieNode));
    node->cnt=0;
    node->exist=false;
    memset(node->next,0,sizeof(node->next));//初始化数组为未标记
    return node;

}
void trieInsert(Trie root,char *str){
    Trie node = root;
    char *p=str;
    int id;
    while( *p ){
        id = *p - 'a';
        if(node->next[id]==NULL){//下一个为空
            node->next[id] = createTrieNode();
        }
        node = node -> next[id];//标记指针下移
        ++p;
        node->cnt+=1;//记录前缀的个数
    }
    node->exist = true;//该单词存在
}
int trieSearch(Trie root,char *str){//查询前缀的个数
    Trie node = root;
    char *p = str;
    while( *p ){

        int id = *p - 'a';
        node = node->next[id];
        ++p;
        if(node==NULL){//没有该单词
            return 0;
        }
    }
    return node->cnt;//返回次数
}

//方法二hash
void showHash(){
    map<string,int> cnt;
    string s;
    int n,m;
    while(cin>>n){
        cnt.clear();
        for(int i=0;i<n;i++){
            cin>>s;
            string ss="";
            for(int i=0;i<s.size();i++){
                ss+=s[i];
                cnt[ss]++;//记录每一个前缀的出现次数
            }
        }
        cin>>m;
        for(int i=0;i<m;i++){
            cin>>s;
            cout<<cnt[s]<<endl;
        }
    }
}


int main()
{

    //freopen("E:/input.txt","r",stdin);
    //freopen("E:/output.txt","w",stdout);
    char str[15];
    int n,m;
    while(scanf("%d",&n)==1){
        Trie root = createTrieNode();//初始化根节点
        for(int i=0;i<n;i++){
            scanf("%s",str);
            trieInsert(root , str);
        }
        scanf("%d",&m);
        for(int i=0;i<m;i++){
            scanf("%s",str);
            printf("%d\n",trieSearch(root,str));
        }
    }

    //showHash();
    return 0;
}

trie树详解:
Trie树详解及其应用(引用)

利用 TensorFlow 训练自己的目标识别器。本文内容来自于我的毕业设计,基于 TensorFlow 1.15.0,其他 TensorFlow 版本运行可能存在问题。.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值