以下是固定存储字符的字典树。 可以以空间换时间,变为可变长的字典树,不过这样的话,查找就会费时了。
#pragma comment(linker, "/STACK:10240000,10240000")
#include<iostream>
#include <vector>
#include <memory>
#define node_size 70
#define maxlen 100
const char trie_begin_ch = 'a';
char tmp[maxlen], substring[maxlen];
int result = 0;
using namespace std;
int k;
class TriTreeNode
{
public:
TriTreeNode();
~TriTreeNode();
std::vector<std::shared_ptr<TriTreeNode>> ptr_next;
void test(bool &w, bool &l);//bool &w, bool &l
};
class TriTree
{
public:
TriTree();
bool insertEle(char *str);
void test();
private:
std::shared_ptr<TriTreeNode> root_;
};
void TriTreeNode::test(bool &w, bool &l)//
{
bool tmp_w = 1, tmp_l = 0, flag = true;
for (auto &tmp : ptr_next)
{
if (NULL != tmp)
{
tmp->test(tmp_w, tmp_l);//tmp_w, tmp_l
// &= tmp->w_flag;
// |= tmp->l_flag;
flag = false;
}
}
// std::cout<<tmp_w<<'\t'<<tmp_l;
if (flag)
{
tmp_w = tmp_l = 0;
}
else
{
tmp_w = 1 - tmp_w;
tmp_l = 1 - tmp_l;
}
w &= tmp_w;
l |= tmp_l;
}
TriTreeNode::TriTreeNode()
{
ptr_next.resize(node_size);
/*for (auto &tmp:ptr_next)
{
tmp = NULL;
}*/
}
TriTreeNode::~TriTreeNode()
{
// for (auto &tmp:ptr_next)
// {
// delete tmp;
// }
}
TriTree::TriTree()
{
root_ = std::make_shared<TriTreeNode>();
}
void TriTree::test()//std::shared_ptr<TriTreeNode>
{
bool tmp_w = 1, tmp_l = 0;
root_->test(tmp_w, tmp_l);
// std::cout<<root_->w_flag<<'\t'<<root_->l_flag<<std::endl;
if (!tmp_w)
{
printf("Second\n");
}
else
{
if (!tmp_l)
{
printf("First\n");
}
else
{
if (k &= 1)
{
printf("First\n");
}
else
{
printf("Second\n");
}
}
}
}
bool TriTree::insertEle(char *str)
{
std::shared_ptr<TriTreeNode> tmp_p = root_;
int len = strlen(str), index;
for (int i = 0; i<len; ++i)
{
index = str[i] - trie_begin_ch;
if (NULL != tmp_p->ptr_next[index])
{
tmp_p = tmp_p->ptr_next[index];
}
else
{
do
{
tmp_p = tmp_p->ptr_next[index] = std::make_shared<TriTreeNode>();
index = str[++i] - trie_begin_ch;
} while (i<len);
return true;
}
}
return false;
}
int main()
{
int n;
scanf("%s", tmp);
int len = strlen(tmp);
TriTree mytree;
cout << len << endl;
for (int i = 2; i <= len; i+=2)
{
int bound = len - i;
for (int j = 0; j <= bound; ++j)
{
int num = 0;
for (int k = j; k < j + i; ++k)
{
substring[num++] = tmp[k];
}
bool flag = true;
int sublen = num / 2;
for (int k = 0; k < sublen; ++k)
{
if (substring[k] != substring[k + sublen])
{
flag = false;
break;
}
}
if (flag)
{
if (mytree.insertEle(substring))
{
++result;
}
}
}
}
cout << result << endl;
/* TriTree mytree;
scanf("%d%d", &n, &k);
for (int i = 0; i<n; ++i)
{
scanf("%s", tmp);
// std::cout<<strlen(tmp)<<std::endl;
if (mytree.insertEle(tmp))
{
}
// std::cout<<<<std::endl;
}
mytree.test();*/
return 0;
}