POJ 1200 Crazy Search

題目意思大概就是
輸入n 和nc 還有一個字符串
字符串的長度不超過16 Millions
As an example, consider N=3, NC=4 and the text "daababac". The different substrings of size 3 that can be found in this text are: "daa"; "aab"; "aba"; "bab"; "bac". Therefore, the answer should be 5.

這里的n=3的意思很明顯就是為了把這個字符串按3的長度分割開,然后統計有多少個不同的
nc就是告訴你整個字符串里只有nc個不同的字母,其他的都是重復的字母

Sample Input

3 4
daababac
Sample Output

5

這題看起來就可以用hash,我當時一次想的時候就是在想這個地址沖突的問題,想怎么能夠有效的避免這個地址的沖突
就有想用map在規避這個地址沖突的問題,后面我看到這個nc一直不能理解這個變量的含義
這個題nc就是我們求key的核心了,
我們開始講這個題的思想拉

第一步 這個nc怎么用 ,這里nc是代表不同的字母那么,是不是可以用nc來做編號?
例如
daababac
第一個是d
那d是第一個出現的我們就給d這個字母設置一個0的編號
a是第二個是 1
b是第三個是 2
c是第四個是 3
那我們怎么用呢?

daa是不是第一個分割好的字符串
那d=0,a=1
key = 0
key = key * nc + asc[d] 這里的asc[d]就是0拉 為什么呢,d = ASCLL=100 所以我們這里直接訪問到 asc [100]這個數組里存的就是我們的d的編號所以是0
那么第一次
key=0 x 4+0; key=0
第二次
key=0 x 4+asc[a]; asc[a]=1 key =1
第三次
key=1 x 4+asc[a]; key = 5
所以我們就得到一個沒有沖突的key 表示的就是hash表里5這個位置
為什么說沒有沖突呢?
例如 ada
第一次
key = 0 x 4 +asc[a] ; key=1;
第二次
key = 1 x 4 +asc[b]; key=4;
第三次
key = 4 x 4 + asc[a]; key=17

例如aad
第一次
key = 0 x 4 + asc[a] ; key = 1
第二次
key = 1 x 4 + asc[a] ; key = 5
第三次
key = 5 x 4 + asc[b]; key = 20
所以說這樣是可以避免沖突的
什么時候會沖突
那就是再次出現重復的字符串
所以這個操作可以讓我們避免重復記錄
第一次得到key訪問這個hash[key] 值為 0 我們就記錄 不同的字符串+1 并把這個hash[kay]變成 1 下次重復的字符串就不會在加在我們的統計里

QQ截圖20180115140637.png

這里有個小問題我之前提交是TLE 發現是因為我的循環里用了strlen()導致我超時了
大家以后需要用到長度的時候最好把長度先求出好放在一個變量里下次使用的時候就可以直接使用了不需要每次都去求

AC代碼

include <stdio.h>

include <string.h>

char str[16000003];
int hash[16000003];
int asc[256]; //這里的256是因為鍵盤上讀取到的最多255

int main()
{
int n,m;
while(scanf("%d %d",&n,&m)!=EOF)
{
memset(hash,0,sizeof(hash));
memset(asc,0,sizeof(asc));
scanf("%s",str);
int len=0;
int stlen=strlen(str);
for(int i=0;i<stlen && len<m;i++) //m是字符串中不同字母的數量,len==m說明剩下的都是相同的了
if(asc[str[i]]==0) //這里是為了給各個字母賦值一個編號
asc[str[i]]=len++; //第一個出現的就是0

    int tot=0;
    stlen=stlen-n+1;              //這里為什么要減n呢    我們是不是要求每n長度的字符串 ,這是為了保證每個字符串的長度都是n
    for(int i=0;i<stlen;i++)
    {
        int sum=0;
        for(int j=0;j<n;j++)
            sum=sum*m+asc[str[j+i]];
        if(hash[sum]==0)
        {
            hash[sum]=1;
            tot++;
        }
    }
    printf("%d\n",tot);
}
return 0;

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。