zoukankan      html  css  js  c++  java
  • POJ2945(Find the Clones)--字典树,map

    题意:给你n个规定长度的单词,问你其中出现了1次的单词,出现两次的单词...出现n次单词分别有多少个。

    当然这题map也能过,但是这里介绍字典树的做法。

    首相对于n个单词存入树中,当然建树过程中遇到一样的单词就把那个单词最后一个结点的计数++就行。否则为这个单词是第一次建立,计数为1。

    count[i]数组用来存放出现i次的字符串出现的次数。

    Travel函数用来递归统计每个单词,将不同出现次数的数字记录到arr数组中,最后打印count数组即可

      1 #include <iostream>
      2 #include <string>
      3 #include <cstring>
      4 #include <fstream>
      5 #include <map>
      6 #include <algorithm>
      7 #include <sstream>
      8 #include <cstdio>
      9 using namespace std;
     10 
     11 const int LetterCount = 26;//最大长度
     12 
     13 struct Node
     14 {
     15     Node* next[LetterCount];//结点的下一个指针
     16     int count;
     17     bool end;//标记是否为最后一个单词
     18     Node();
     19 };
     20 
     21 Node::Node()
     22 {
     23     for (int i = 0; i < LetterCount; i++)
     24     {
     25         next[i] = NULL;
     26     }
     27     count = 1;
     28     end = false;
     29 }
     30 
     31 class Trie
     32 {
     33 protected:
     34     Node* root;
     35     void GreateRoot();
     36     void Distroy(const Node* root);
     37     void Travel(Node* root, int* arr);
     38 public:
     39     Trie();
     40     ~Trie();
     41     int Insert(char* word);
     42     int Query(char* word);
     43     void Travel(int* arr, int n);
     44 };
     45 
     46 Trie::Trie()
     47 {
     48     root = NULL;
     49     GreateRoot();
     50 }
     51 
     52 Trie::~Trie()
     53 {
     54     Distroy(root);
     55 }
     56 
     57 void Trie::GreateRoot()
     58 {
     59     if (!root)//根结点为false
     60     {
     61         root = new Node();//建根
     62         for (int i = 0; i < LetterCount; i++)
     63         {
     64             root->next[i] = NULL;
     65         }
     66     }
     67 }
     68 
     69 void Trie::Distroy(const Node* root)
     70 {
     71     if (!root)
     72     {
     73         return;
     74     }
     75     for (int i = 0; i < LetterCount; i++)
     76     {
     77         if (root->next[i] != NULL)
     78         {
     79             Distroy(root->next[i]);
     80         }
     81     }
     82     delete[] root;
     83 }
     84 
     85 int Trie::Insert(char* word)
     86 {
     87     Node* p = root;//根结点为root
     88     int length = strlen(word);//计算长度
     89     for (int i = 0; i < length; i++)
     90     {
     91         int index = word[i] - 'A';
     92         if (!(p->next[index]))//当前没有那个字母
     93         {
     94             Node* q = new Node();
     95             q->end = false;
     96             for (int j = 0; j < LetterCount; j++)
     97             {
     98                 q->next[j] = NULL;
     99             }
    100             p->next[index] = q;
    101         }
    102         p = p->next[index];
    103     }
    104     if (p->end)
    105     {
    106         p->count++;
    107     }
    108     else
    109     {
    110         p->end = true;
    111         p->count = 1;
    112     }
    113     return p->count;
    114 }
    115 
    116 int Trie::Query(char* word)
    117 {
    118     Node* p = root;
    119     bool found = true;
    120     int length = strlen(word);
    121     for (int i = 0; i < length; i++)
    122     {
    123         int index = word[i] - 'A';
    124         p = p->next[index];
    125         if (!p)//p为false
    126         {
    127             found = false;//没找到
    128             break;
    129         }
    130     }
    131     if (!found || !p->end)//没找到或已经是结束标记
    132     {
    133         return 0;
    134     }
    135     return p->count;//否则返回计数
    136 }
    137 
    138 void Trie::Travel(Node* root, int* arr)
    139 {
    140     if (!root)
    141     {
    142         return;
    143     }
    144     if (root->end)//表示为最后一个词
    145     {
    146         arr[root->count]++;
    147         return;
    148     }
    149     for (int i = 0; i < LetterCount; i++)
    150     {
    151         Travel(root->next[i], arr);//递归计算
    152     }
    153 }
    154 
    155 void Trie::Travel(int* arr, int n)
    156 {
    157     for (int i = 0; i < n; i++)
    158     {
    159         arr[i] = 0;
    160     }
    161     Travel(root, arr);
    162 }
    163 
    164 class FindTheClones
    165 {
    166 protected:
    167     int n;
    168     int* count;
    169     Trie tree;
    170 public:
    171     FindTheClones(int n);
    172     ~FindTheClones();
    173     void Insert(char* word);
    174     void Travel();
    175     void Output() const;
    176 };
    177 
    178 FindTheClones::FindTheClones(int n)
    179 {
    180     this->n = n;
    181     count = new int[n + 1];
    182     memset(count, 0, sizeof(int) * (n + 1));
    183 }
    184 
    185 FindTheClones::~FindTheClones()
    186 {
    187     delete[] count;
    188 }
    189 
    190 void FindTheClones::Insert(char* word)
    191 {
    192     tree.Insert(word);
    193 }
    194 
    195 void FindTheClones::Travel()
    196 {
    197     tree.Travel(count, n + 1);
    198 }
    199 
    200 void FindTheClones::Output() const
    201 {
    202     for (int i = 1; i < n + 1; i++)
    203     {
    204         printf("%d
    ", count[i]);
    205     }
    206 }
    207 
    208 int main()
    209 {
    210     int n = 0, m = 0;
    211     while (scanf("%d%d", &n, &m))
    212     {
    213         if (n <= 0)
    214         {
    215             break;
    216         }
    217         char str[32];
    218         FindTheClones obj(n);
    219         for (int i = 0; i < n; i++)
    220         {
    221             scanf("%s", str);
    222             obj.Insert(str);
    223         }
    224         obj.Travel();
    225         obj.Output();
    226     }
    227     return 0;
    228 }
    View Code
  • 相关阅读:
    Python3之网络编程
    Python3之内置函数
    Python3之面向对象
    Python3之函数
    Python3基础数据类型-字符串
    else配合while或者for循环只用注意点
    字符串
    元组
    48964
    1651
  • 原文地址:https://www.cnblogs.com/ygsworld/p/11173241.html
Copyright © 2011-2022 走看看