今天是我第一次接触树,学习树;碰到了这个问题;结果上网看了看别人的代码,发现解法多样,这篇文章不是写AC代码的(虽然代码都能AC)而是写我对这不同解法的理解与感悟;以及第一天学习下来的成果。 ---Keep Codeing---
Hdu1251 统计难题
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=69422#problem/E
解法一:建立一颗树,因为这里有26个字符,因此建立字母树
#include <iostream>
#include <cstdio>
#include <cstring>
//char *str;
char *question[100];
struct Node
{
int num; //记录当前结点的子树个数;
Node *child[26]; //最多有26个子树;下标可以保存当前的字符 ch-'a'
}*root;
void BuiltTree(char *s) //增加一个字串
{
Node *t, *p; //目标指针
p = root; //目标指针指向根节点
int n = strlen(s);
int i;
for(i = 0; i < n;i++)
{
if(p->child[s[i]-'a'] == NULL) //如果该节点没有这个子结点
{
t = new Node; //,申请内存空间
t->num = 1; //并将这个子结点的num变为1(表示自己一个子树);
for(int j = 0; j < 26;j++) //将这个新的子节点的子节点变为空(因为它本身也是新增的,所以子节点必为空)
{
t->child[j] = NULL;
}
p->child[s[i]-'a'] = t; //关键的一步,将对象结点的子节点保存该子结点的子结点;
}
else p->child[s[i]-'a']->num++; //有该结点就将该结点num + 1;(表示新增了一个子树);
p = p->child[s[i]-'a']; //目标指针指向下一个结点
}
}
void InitRoot()//初始化根结点
{
root = new Node; //为根结点申请空间
root->num = 0; //计数为 0(不属于字符串的一部分)
for(int i = 0; i < 26;i++)
{
root->child[i] = NULL;
}
}
int SearchTree(char *s)
{
Node *p; //目标指针
int n = strlen(s);
p = root;
for(int i = 0; i < n;i++)
{
if(p->child[s[i]-'a'] == NULL) //循环还没结束 ,到某个字符找不到了,证明没有满足前缀所有字符的字符串,因此返回0;
{
return 0;
}
p = p->child[s[i]-'a']; //如果上一个字符满足前缀,则指向下一个字符;
}
return p->num; // 循环结束前没有返回证明至少找到前缀满足的字符串,只要输出该结点的num的值即可
}
int main()
{
char str[15];
InitRoot();
while(1)
{
gets(str);
if(strcmp(str,"") == 0)
break;
BuiltTree(str);
}
while(~scanf("%s",str))
{
printf("%d\n",SearchTree(str));
}
return 0;
}
</cstring></cstdio></iostream>