UVA - 11732 "strcmp()" Anyone?左兄弟右儿子trie

input

n 2<=n<=4000

s1

s2

...

sn

1<=len(si)<=1000

output

输出用strcmp()两两比较si,sj(i!=j)要比较的次数,结果在long long范围内(相同字符比较两次,不相同字符比较一次,包括'\0')

做法:由于字符集太大,要用左兄弟右儿子的trie保存字符,不用每次都开ch[62]个孩子

 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <map>
 9 #include <set>
10 #include <ctime>
11 #include <cmath>
12 #include <cctype>
13 #define MAX 100000
14 #define LL long long
15 #define mod 20071027
16 struct node
17 {
18     int sz;
19     char val;
20     node*ch[2];            //ch[1]兄弟,ch[0]儿子
21     node()
22     {
23         ch[0]=ch[1]=NULL;
24         sz=0;
25     }
26 };
27 char word[1010];
28 int n,cas=1;
29 long long sum;
30 long long insert(char*s,node*u)
31 {
32     long long sum=0,lastsz=u->sz++;
33     for(;*s||*(s-1);s++)
34     {
35         if(!u->ch[0])            //易错,要先把新建的结点连接到父结点才能往下走,否则新建之后父节点无法再读取到该结点
36         {
37             u->ch[0]=new node;
38             u->ch[0]->val=*s;
39         }    
40         for(u=u->ch[0];u->val!=*s;u=u->ch[1])
41         {
42             if(!u->ch[1])
43             {
44                 u->ch[1]=new node;
45                 u->ch[1]->val=*s;
46             }
47         }    
48         sum+=lastsz+u->sz;
49         lastsz=u->sz++;
50     }
51     return sum;
52 }
53 /*//这样可以将父节点的ch和新建的结点绑定起来,传过来的是&root
54 long long insert(char*s,node**u)
55 {
56     long long sum=0,lastsz=(*u)->sz++;
57     for(;*s||*(s-1);s++)
58     {
59         printf("%p\n",u);
60         for(u=&((*u)->ch[0]);(*u)&&(*u)->val!=*s;u=&((*u)->ch[1]));
61         if(*u==NULL)
62         {
63             *u=new node;
64             (*u)->ch[0]=(*u)->ch[1]=NULL;
65             (*u)->val=*s;
66         }
67         sum+=lastsz+(*u)->sz;
68         lastsz=(*u)->sz++;
69     }
70     return sum;
71 }*/
72 void freenode(node*u)
73 {
74     if(u==NULL) return;
75     freenode(u->ch[0]);
76     freenode(u->ch[1]);
77     delete u;
78 }
79 int main()
80 {
81     //freopen("/home/user/桌面/in","r",stdin);
82     while(scanf("%d",&n)==1&&n)
83     {
84         sum=0;
85         node *root=new node;
86         while(n--)
87         {
88             scanf("%s",word);
89             sum+=insert(word,root);
90         }
91         printf("Case %d: %lld\n",cas++,sum);
92         freenode(root);
93     }
94     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
95     return 0;
96 }
97 
98 my Code
my Code
 1 #include <cstdio>  
 2 #include <cstring>  
 3 #include <iostream>  
 4 #include <algorithm>  
 5 using namespace std;  
 6   
 7 #define repf(i,a,b) for(int i=(a);i<=(b);i++)  
 8 typedef long long ll;  
 9   
10 const int N = 0;  
11 const int MAXNODE = 4000010;  
12   
13 int n, cas;  
14 ll ans;  
15 char str[4001];  
16   
17 struct STrie {  
18     int son[MAXNODE];  
19     int bro[MAXNODE];  
20     int val[MAXNODE];  
21     char ch[MAXNODE];  
22     int sz;  
23   
24     STrie() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }  
25     void init() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }  
26     // inline int idx(char c) { return c - 'a'; }  
27       
28     void insert(char *s) {  
29         int len = strlen(s), u = 0, p;  
30         repf (i, 0, len) {  
31             // check the brother of u  
32             for (p = son[u]; p; p = bro[p]) {  
33                 if (ch[p] == s[i])  
34                     break;  
35             }  
36             // cannot find out than insert  
37             if (!p) {  
38                 p = sz++;  
39                 ch[p] = s[i];  
40                 bro[p] = son[u];  
41                 son[p] = 0;  
42                 val[p] = 0;  
43                 son[u] = p;  
44             }  
45             ans += (val[u] - val[p]) * (2 * i + 1);  
46             if (len == i) {  
47                 ans += val[p] * (2 * i + 2);  
48                 val[p]++;  
49             }  
50             val[u]++;  
51             u = p;  
52         }  
53     }  
54 } trie;  
55   
56 int main() {  
57     // ios_base::sync_with_stdio(0);  
58     while (~scanf("%d", &n) && n) {  
59         trie.init();  
60         ans = 0;  
61         repf (i, 0, n - 1) {  
62             scanf("%s", str);  
63             trie.insert(str);  
64         }  
65         printf("Case %d: %lld\n", ++cas, ans);  
66     }  
67     return 0;  
68 } 
copy Code

转载于:https://www.cnblogs.com/cdyboke/p/5015540.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,C++中确实有`strcmp`函数。`strcmp`是一个字符串比较函数,用于比较两个字符串是否相等。它是在C++标准库中的`<cstring>`(在C++11及以后的版本中,这个库通常被重命名为`<string>`)中定义的。 函数的原型通常如下: ```cpp int strcmp(const char *str1, const char *str2); ``` 这个函数会返回一个整数,如果`str1`和`str2`完全相同,它会返回0。如果`str1`在字典序上小于`str2`,它会返回一个负数。如果`str1`在字典序上大于`str2`,它会返回一个正数。 使用这个函数时,需要注意以下几点: * 字符串必须以空字符('\0')结尾,否则可能会产生未定义的行为。 * 字符串必须以空字符结尾的相同方式进行比较。否则可能会得到错误的结果。 * 两个字符串的指针参数不能是NULL,否则会抛出运行时错误。 使用这个函数的一个例子可能是这样的: ```cpp #include <cstring> #include <iostream> int main() { std::string str1 = "Hello"; std::string str2 = "Hello"; int result = strcmp(str1.c_str(), str2.c_str()); if (result == 0) { std::cout << "Strings are equal." << std::endl; } else if (result < 0) { std::cout << "String1 is less than String2." << std::endl; } else { std::cout << "String1 is greater than String2." << std::endl; } return 0; } ``` 这个程序将打印出 "Strings are equal.",因为两个字符串是相同的。请注意,为了安全起见,最好始终使用字符串的`.c_str()`方法来获取C风格的字符串,以便在需要使用`strcmp`或类似函数的情况下使用它们。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值