Reverse word dictionary tree HIhoCoder 1366

Reverse word order dictionary HIhoCoder 1366

The meaning of problems

There are many reverse order of words in the English language, such as dog and god, evil and live and so on.

Now given a list of words that contains N words, where each word appears only once, you find out how many of the words in reverse order.

Line 1: an integer, N, is the number of words. 2≤N≤50,000.

The first line 2..N + 1: 1 word per line, only lowercase letters, each word length does not exceed 16 characters. Ensure that each word appears only once, and will not appear palindromic word (that is, a word or reverse its own, such as eye).

The first output line is an integer representing the number of words in reverse order word list.

Problem-solving ideas

I think this is a B station learning problems seen on the dictionary order, basically a template title. For more details, see the code that implements it.

Code

Trie generally implemented in two ways, the distinction is established from node A is established using the new allocation of space, the other is open a predetermined array.

The following are two forms of codes. The second run faster.

#include<bits/stdc++.h> //时间是453ms
using namespace std;
struct Node
{
    Node *next[26]; //对应26个小写英文字母
    int flag; //这个记录从根节点到现在这个结点组成的单词是不是存在的单词,如果有多个的话,可以记录个数。
    Node()//构造函数
    {
        for(int i=0; i<26; i++)
            next[i]=NULL;
        flag=0;
    }
}*root;//这个root是字典树的第一个结点,也就是树的根。

void insert(char *s) //插入操作
{
    int len=strlen(s);
    Node *now = root;
    for(int i=len-1; i>=0; i--) //根据题目要求,这里使用逆序插入比较好。
    {
        int to=s[i]-'a';
        if(now->next[to]==NULL) //如果没有子节点,就建立。
            now->next[to]=new Node();
        now=now->next[to];//然后进入到下一个单词的子节点。
    }
    now->flag++; //可能有多个单词 
}
int fid(char *s)//查找函数
{
    int len=strlen(s);
    Node *now=root;
    for(int i=0; i<len; i++)//这里就是正向查找了
    {
        int to=s[i]-'a';
        if(now->next[to]==NULL)
            return 0;
        now=now->next[to];
    }
    return now->flag;//返回以这个结点为尾的单词的个数
} 
void del(Node *rot) //因为使用的是new分配的空间,所以使用完毕需要进行删除。
{
    for(int i=0; i<26; i++)
    {
        if(rot->next[i])
            del(rot->next[i]);//递归形式的删除。
    }
    delete(rot);
}
int main()
{
    int n, ans=0;
    char op[20];
    root = new Node();
    scanf("%d",&n);
    getchar();
    for(int i=0; i<n; i++)
    {
        scanf("%s", op);
        ans+=fid(op);
        insert(op);
    }
    printf("%d\n", ans);
    del(root);
    return 0;
}
#include<bits/stdc++.h> //时间是242ms
using namespace std;
const int maxn=2e6+7;
int tree[maxn][27];
int flag[maxn];
int tot; 
void insert(char *str)
{
    int len=strlen(str);
    int root=0;
    for(int i=len-1; i>=0; i--)
    {
        int id=str[i]-'a';
        if(!tree[root][id])
            tree[root][id]=++tot; //类似于邻接链表的形式来建立
        root=tree[root][id];
    }
    flag[root]++;
}
int find(char *str) //需要根据需要进行匹配 
{
    int len=strlen(str);
    int root=0;
    for(int i=0; i<len; i++)
    {
        int id=str[i]-'a';
        if(!tree[root][id])
            return 0;
        root=tree[root][id];
    }
    return flag[root];
}
int main()
{
    int n, ans=0;
    char op[20];
    scanf("%d",&n);
    getchar();
    for(int i=0; i<n; i++)
    {
        scanf("%s", op);
        ans+=find(op);
        insert(op);
    }
    printf("%d\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/alking1001/p/11762089.html