trie树(静态建树)

poj1002

题意:输入一个字符串,除去空格后映射成一个7位数的数字串。判断字符是否有重复,如果有则输出字串及字串重复的个数,如果没有则输出"No duplicates."(这里要注意Q和Z都没映射,则为0)。

题解:判重,可以将处理后的n个7位数字串用qsort处理,或者用trie数加dfs(其中用val[]值保存出现改字串的个数)。

#include <iostream>
#include <string.h>
#include <cstdio>

using namespace std;

int trie[1000005][10];
int val[1000005];
int sz;

int cnt[100005];
char ans[100005][10];
int res;

void Init() {
  memset(trie[0], 0, sizeof(trie[0][10]));
  sz = 1;
}

int Index(char c){
  if(c == 'A' || c == 'B' || c == 'C') return 2;
  else if(c == 'D' || c == 'E' || c == 'F') return 3;
  else if(c == 'G' || c == 'H' || c == 'I') return 4;
  else if(c == 'J' || c == 'K' || c == 'L') return 5;
  else if(c == 'M' || c == 'N' || c == 'O') return 6;
  else if(c == 'P' || c == 'R' || c == 'S') return 7;
  else if(c == 'T' || c == 'U' || c == 'V') return 8;
  else if(c == 'W' || c == 'X' || c == 'Y') return 9;
  else if(c >= '0' && c <= '9') return c-'0';
  else if(c == 'Q' || c == 'Z') return 0;
}

void Insert(int root, char *data) {
  int len = strlen(data);
  int u = root;
  for(int i = 0; i < len; i ++){
    if(data[i] == '-') continue;
    int ch = Index(data[i]);
    if(trie[u][ch] == 0){
      memset(trie[sz], 0, sizeof(trie[sz]));
      trie[u][ch] = sz;
      val[sz] = 0;
      sz ++;
    }
    u = trie[u][ch];
  }
  val[u] ++;
}

void print_word(char *temp, int num, int root){
  for(int i = 0; i < num; i ++)
      ans[res][i] = temp[i];
  cnt[res] = val[root];
  res ++;
}

void dfs(int root, char *temp, int num){
  if(val[root] > 0) print_word(temp, num, root);
    for(int i = 0; i < 10; i ++){
      if(trie[root][i] != 0){
        temp[num] = i + '0';
        dfs(trie[root][i], temp, num+1);
      }
    }
}

void Traverse(int root){
  char temp[10005];
  dfs(0, temp, 0);
}

int main()
{
  int t;
  char data[1000];
  scanf("%d", &t);
  Init();
  for(int i = 0; i < t; i ++){
    scanf("%s", data);
    Insert(0, data);
  }
  res = 0;
  Traverse(0);
  // cout << res << endl;
  int flag = 0;
  for(int i = 0; i < res; i ++)
    if(cnt[i] > 1) {
        for(int j = 0; j < strlen(ans[i]); j ++){
          if(j == 3) printf("-%c", ans[i][j]);
          else printf("%c", ans[i][j]);
        }
        printf(" %d\n", cnt[i]);
        flag = 1;
    }
  if(flag == 0) printf("No duplicates.\n");
  // 没有两个是相同的
  return 0;
}


 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值