【洛谷】 P3879 [TJOI2010]閱讀理解

【洛谷】 P3879 [TJOI2010]閱讀理解


0.總結

Get to the points first. The article comes from LawsonAbs!
  • trie樹
  • 二維數組隱式越界坑

1.題意

判斷一個單詞是否出現在某串文本中。如果出現,則輸出文本的序號【按照從小到大的方式】,否則直接輸出換行。

2.分析

典型的模板題,使用 trie 就可以解決。這裏我不再介紹tried樹了,簡單說一下我的主要解決步驟:

  • step 1.使用一個trie 數組用於存儲每串文本的結構。由題意知,可以設計一個三維數組 trie[][][] ,其中第一維表示的是第幾篇閱讀;第二維表示節點個數;第三維表示指向【類同二維的tried數組】
  • step 2.依次遍歷每個查詢字符串,然後輸出即可。

3.代碼

// Created by lawson on 20-6-21.
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxN = 1005; //表示最大的短文數,同時也作爲最大的個數
const int maxM = 20000;
int n,m;//n表示短文數
short trie[maxN][maxM][27];// 26個小寫字母
int p = 0,cnt = 1,tot = 0;//cnt 表示第幾篇短文;
bool endF[maxN][maxN];//結束標誌 => 用bool省空間

void build(char in[] ){
    int p = 0;
    for(int i = 0;i<strlen(in);i++){
        int cNum = in[i]-'a';
        if(!trie[cnt][p][cNum]){//如果沒有記錄
            trie[cnt][p][cNum] = ++tot;
        }
        p = trie[cnt][p][cNum];//更新p的值
    }
    endF[cnt][p] = true;
}

//查詢in這個字符串是否在trie樹中
bool search(int index,char in[]){
    p = 0;
    for(int i = 0;i<strlen(in);i++){
        int cNum = in[i]-'a';
        if(!trie[index][p][cNum])
            return false;
        else
            p = trie[index][p][cNum];
    }
    if(endF[index][p])
        return true;
    return false;
}

int main(){
    scanf("%d",&n);
    while(cnt<=n){
        tot = 0;//重置爲0
        scanf("%d",&m);
        char word[30];//每個字符長20
        for(int i = 1;i<=m;i++){
            scanf("%s",word);//輸入每個單詞
            build(word);
        }
        cnt++;
    }

    scanf("%d",&m);

    char query[25];//待查詢的字符串
    for(int i = 1;i<= m;i++){
        int res[maxN];//存儲答案
        cnt = 0;//重置
        scanf("%s",query);
        for(int j = 1;j<=n;j++)
            if(search(j,query))
                res[cnt++] = j;
        //更換輸出格式
        for(int j = 0;j<cnt;j++)
            if(j!=cnt-1)    printf("%d ",res[j]);
            else printf("%d",res[j]);

        printf("\n");//輸出一個空行
    }
}

4.測試用例

2
1 youare
3 my name is
2
you
you

1
3 you you you
1
you

1
4 you a good person
1
yo

3
9 you are a good boy ha ha o yeah
13 o my god you like bleach naruto one piece and so do i
11 but i do not think you will get all the points
5
yo
s
o
all
all

5.坑點

  • 需要注意數組大小的申請,一般情況下,很難得到一個**“高維數組的越界提示”**,比如說二維數組 arr[10][10],你如果用 arr[5][20] 依然是可以訪問到值!所以一定要注意題目的數據範圍大小到底需要一個什麼範圍的數組!千萬別模棱兩可。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章