poj 1200 Crazy Search

超内存:有时候写一个memset,也可能造成超内存的现象:

题目大概意思是:n 代表字串的长度,nc 代表给出的字符串中含有的字符种类数 再给出一个字符串 找出在这个字符串中长度为n 的不同的字串的个数

题目中的最大值为16 Millions 是一千六百万,也就是说给出的字符串中最多可以含有一千六百万个字符

所以我们需要设一个大约是一千六百万的字符数组

具体的解题思路是:将字符串的子字符串转化成数字,放到一个数组里,再进行哈希查找,而这个哈希数组可以开到两千万我试过了,不会超内存,但是我计算的 是会超的算了下面再算算好了;

1 将nc 个字母都编成数字,直接用它的ASCII码就行了 具体代码

                while(ncsize)

{
if(word_map[str[i]]<=0)
{
word_map[str[i]]=ncsize;//字符在int 数组的编号中自动转化成int类型,其值是他的ASCII 码
ncsize--;
}
i++;
}

2 将某一个n个字符的字串转换成数字

int strhash(char *key)
{
int i,h;
h=0;
for(i=0;i<n;i++)
{
h=h*nc+word_map[*(key+i)];
}
return h%maxnum;
}

这里注意对指针的用法 指针代表地址 这里*key代表某一个字符变量的地址 可以用*(key+i)来取得数组中存的值

3 最后就是哈希查找了

       while(str[i+n-1]!='\0')
{
hash_add=strhash(str+i);
if(!hash[hash_add])//判断这个值是否已经存在
{
hash[hash_add]++;
c++;//c记录不同的哈希值的个数,其最终结果就是字字符串的个数
}

              }

整体代码:

第一句话说如果加上memset 会超内存,是滴 在下面这些代码中如果加上对hash 和 word_map数组的初始化就会超内存,你可以试试,具体为什么我也不知道

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxnum 20000000
char str[16000001];
int hash[maxnum],hash_add,word_map[256];
int n,nc,ncsize;
int strhash(char *key)
{
int i,h;
h=0;
for(i=0;i<n;i++)
{
h=h*nc+word_map[*(key+i)];
}
return h%maxnum;
}
int main()
{
int i;
int c;
scanf("%d%d",&n,&nc);
ncsize=nc;
scanf("%s",str);
getchar();
i=0;
while(ncsize)
{
if(word_map[str[i]]<=0)
{
word_map[str[i]]=ncsize;
ncsize--;
}
i++;
}
i=0;
c=0;
while(str[i+n-1]!='\0')
{
hash_add=strhash(str+i);
if(!hash[hash_add])
{
hash[hash_add]++;
c++;
}
i++;
}
printf("%d\n",c);
return 0;
}



你可能感兴趣的:(poj 1200 Crazy Search)