【题目链接】
【题目描述】
在进行文法分析的时候,通常需要检测一个单词是否在我们的单词列表里。为了提高查找和定位的速度,通常都画出与单词列表所对应的单词查找树,其特点如下:
1.根结点不包含字母,除根结点外每一个结点都仅包含一个大写英文字母;
2.从根结点到某一结点,路径上经过的字母依次连起来所构成的字母序列,称为该结点对应的单词。单词列表中的每个单词,都是该单词查找树某个结点所对应的单词;
3.在满足上述条件下,该单词查找树的结点数最少。
4.例如图3-2左边的单词列表就对应于右边的单词查找树。注意,对一个确定的单词列表,请统计对应的单词查找树的结点数(包含根结点)。
【输入】
为一个单词列表,每一行仅包含一个单词和一个换行/回车符。每个单词仅由大写的英文字母组成,长度不超过63个字母 。文件总长度不超过32K,至少有一行数据。
【输出】
仅包含一个整数,该整数为单词列表对应的单词查找树的结点数。
【输入样例】
A
AN
ASP
AS
ASC
ASCII
BAS
BASIC
【输出样例】
13
【题解】
#include <iostream>
using namespace std;
struct TreeNode{
char c;//不适用字符数组的原因是一个结点只会有一个val值 但可能有多个孩子
TreeNode *child[26];//此题并不是单纯二叉树 而是有多个孩子 所以要使用TreeNode *数组
TreeNode(char t){
c = t;
for(int i=0;i<26;i++){
child[i] = nullptr;
}
}
};
//TreeNode *build(TreeNode *root,string s){
// for(char c:s){
// int index = c-'A';
// if(root->child[index]== nullptr)
// root->child[index] = new TreeNode(c);
// root = root->child[index];
// }
// return root;
//}
TreeNode *build(TreeNode *root,string s){
TreeNode *curr = root;//要用一个结点代替遍历 否则会丢失根节点信息
for(char c:s){
int index = c-'A';
if(curr->child[index]== nullptr)
curr->child[index] = new TreeNode(c);
curr = curr->child[index];
}
return root;
}
//int count(TreeNode *root) {
// int cnt = 0;
// for (int i = 0; i < 26; i++) {
// if (root->child[i]!= nullptr) {
// return 1 + count(root->child[i]);//return 程序终止不会继续检查其余非空结点 不能直接进行return 而是记录下来
// }
// }
// return 0;
//}
int count(TreeNode *root){
int cnt=0;
for(int i=0;i<26;i++){
if(root->child[i]!=nullptr){
cnt+=count(root->child[i]);
}
}
return 1+cnt;
}
int main(){
TreeNode *root = new TreeNode('\0');
string s;
while(cin>>s){
root = build(root,s);
}
cout<<count(root);
}