NYOJ 685 查找字符串 字典树 map容器 吐血经验 cin cout 与printf scanf
2013-04-30 11:11
399 查看
早上起来本来想先水一题,竟然被水题给虐了,悲剧啊,顺便公布一下水题歌(原创的哦)白天水一水 不瞌睡,晚上水一水 睡得香。饭前水一水 胃口好,饭后水一水 助消化。看了oj上一题 查找字符串,感觉有点水(如果数据不坑),水水好心情嘛,用map容器写了写,习惯性的用了map<string,int>,当然还习惯的用了cin和cout 编译,运行,超时了!! 顿时感觉是map容器的问题,(这个感觉害了我啊~~)因为map在存入的时候很慢,转念想着用字典树,可行,好换个思路换个方法吧,字典树,动态的字典树,调试 了半天,提交RE了,怎么调试都是RE,后来崩溃的发现了一个傻逼性质的错误,题中有”+“我把他的ASCII码写成了46了,原本是43,难怪RE,不过这都是浮云~~ AC 之后看看比尔的代码顿时崩溃了,和我第一次TLE 的代码几乎一样啊?时间也很少,怎么回事?仔细查看,发现了个很吐血的问题map<string,int> mp;
char s[16];
gets(s);
mp[s]++;
//......
ptintf("%d\n",mp[s]);
而我的代码用的是
string s; cin>>s; mp[s]++; //..... cout<<mp[s]<<endl;
测试了一下1000000的测试数据,时间相差竟然1000多ms,一个144,一个1214!!
以后注意啊,
gets比 scanf 快
scanf 比cin快的多,cout也很慢的。。。吐血经验啊,搞了大半个上午了都纠结
题目如下
查找字符串
时间限制:1000 ms | 内存限制:65535 KB难度:3
描述
小明得到了一张写有奇怪字符串的纸,他想知道一些字符串出现了多少次,但这些字符串太多了,他想找你帮忙,你能帮他吗?输入字符包括所有小写字母、‘@’、‘+’。
输入第一行包含一个整数T(T<=100).表示测试数据组数。
接下来每组数据第一行包含两个整数n,m(n,m<100000),分别表示有n个字符串,小明要问你m次。
接下来n行,每行包含一个字符串,长度不大于15。
接下来m行,每行包含一个字符串,表示小明要问该串出现的次数。
输出输出每组小明询问数串出现的次数。样例输入
1 5 3 hello it@is+so@easy hello ibelieveicanac hello hello icannotacit Giveup
样例输出
3 0 0
顺便给出字典树的模板,对于本题来讲并不需要释放内存,
字典树模型
/* 字典树模板 MAX 代表字典树中一共的字符的个数,例如如果只有数字就9,只有小写字母就是26, 也就是的其中字符的最大ASCII减去最小的加一 ,122-97+1=26; 下面模板 MAX为80 因为题中除了有小写字母还有“+”(43)和“@”(64) 122-43+1=80; */ #include<stdio.h> #include<string.h> #include<stdlib.h> #define MAX 80 typedef struct node { struct node *next[MAX]; /*子节点个数 */ int cnt; }Trie; Trie *root; /*定义根节点*/ Trie* build() /*建立新的节点*/ { Trie *p=(node *)malloc(sizeof(node)); /*动态分配内存*/ p->cnt=0; for(int i=0;i<MAX;i++) { p->next[i]=NULL; /*新建节点的子节点为空*/ } return p; } int insert(char*s) /*建树,插入新的字符串*/ { Trie *p=root; int len=strlen(s); for(int i=0;i<len;i++) { int id=s[i]-'+';/*这里减去的是其中最小的ASCII码对应的字符,这里减‘+'*/ if(p->next[id]!=NULL) p=p->next[id]; else { p->next[id]=build(); p=p->next[id]; } } p->cnt++; return p->cnt;//灵活改变,可以不返回任何值,看题目问什么 } int search(char *s)//查找 { int len=strlen(s); Trie *p=root; for(int i=0;i<len;i++) { int id=s[i]-'+'; if(p->next[id]!=NULL) p=p->next[id]; else return 0; } return p->cnt; } /*大多的字典树不需要释放内存,但是如果内存不够用,应该还原树空间*/ int deleteTrie(Trie *T) { int i; if(T==NULL)return 0; for(i=0;i<MAX;i++) { if(T->next[i]!=NULL) deleteTrie(T->next[i]); } free(T); return 0; } int main() { int T,n,m,i; char s[20]; scanf("%d",&T); while(T--) { root=build(); //循环的开头需要新建根节点; scanf("%d%d",&n,&m); for(i=0;i<n;i++) { scanf("%s",s); insert(s); } for(i=0;i<m;i++) { scanf("%s",s); printf("%d\n",search(s)); } deleteTrie(root);//释放空间 } return 0; }
用map容器写代码:
#include<iostream> #include<cstdio> #include<map> #include<string> using namespace std; map<string,int>mp; int main() { int t; cin>>t; while(t--) { int m,n; char str[18]; scanf("%d%d",&m,&n); a.clear();//记着清空容器 while(m--) { scanf("%s",str); mp[str]++; } while(n--) { scanf("%s",str); printf("%d\n",mp[str]); } } return 0; }
注意map的写法时间是字典树的二倍!!
相关文章推荐
- nyoj685 查找字符串(map)
- NYOJ 685 查找字符串 字典树
- NYOJ685 查找字符串(字典树)
- 7、字符串的输入与输出scanf、printf、cin、cout、gets、puts
- nyoj685查找字符串(字典树)
- NYOJ 题目685 查找字符串(STL----map)
- NYOJ 685 查找字符串(map)
- c++中简单的i/o操作(cin,cout,scanf,printf)
- cin,cout与scanf,printf的速度到底相差多少
- 再一次看到了cin cout比scanf和printf耗时。(有关文件差异的比较方法在后面)
- cin,cout与scanf,printf的速度到底相差多少
- NYOJ 685 查找字符串
- cin cout scanf printf
- scanf printf 与cin cout 时间的差别
- c/c++ cin>> cout<< scanf() printf() 返回值
- cin,cout与scanf,printf 差别
- printf,scanf,cin,cout的输入输出
- nyoj 685 查找字符串
- cin、cout 与 scanf、printf 的效率比较
- scanf,cin,printf,cout,putchar效率比较