1. 程式人生 > >藍橋杯 演算法訓練 字串統計 By Assassin 字串操作+離散化

藍橋杯 演算法訓練 字串統計 By Assassin 字串操作+離散化

問題描述
  給定一個長度為n的字串S,還有一個數字L,統計長度大於等於L的出現次數最多的子串(不同的出現可以相交),如果有多個,輸出最長的,如果仍然有多個,輸出第一次出現最早的。
輸入格式
  第一行一個數字L。
  第二行是字串S。
  L大於0,且不超過S的長度。
輸出格式
  一行,題目要求的字串。

  輸入樣例1:
  4
  bbaabbaaaaa

  輸出樣例1:
  bbaa

  輸入樣例2:
  2
  bbaabbaaaaa

  輸出樣例2:
  aa
資料規模和約定
  n<=60
  S中所有字元都是小寫英文字母。
提示
  列舉所有可能的子串,統計出現次數,找出符合條件的那個

其實這道題是一個簡單的字串操作,只不過在處理這個問題的時候用到了一下小技巧,比如string字串操作,map迭代器的使用,簡單的離散化思想,和自定義的sort函式,對於新手還是值得學習一下的

首先我們明確資料範圍就是n<=60,那麼其實明顯用字串暴力記錄就可以了,但是這裡買你還有一定的規則,就是如果有多個,輸出最長的,如果仍然有多個,輸出第一次出現最早的

那麼我是這麼處理的,我們在記錄string串用map 《string , int》,因為N<=60那麼出現的最多次數不過是L=1,n=60吧!那麼出現的次數最多60次吧,那麼我們在處理int記錄次數的時候,加上起點位置*一個大數 ,這個大數一定比60大,那麼我們就可以記錄該串起點的位置了,而且每次取個數的時候只需要模一下那個大數就能得到次數!

然後用map迭代器找到出現最多的次數,用結構體記錄出現次數最多的串,然後我們用一個cmp自定義函式排序,具體函式如下:

int cmp(node a,node b){
    if(a.s.size()>b.s.size()) return 1;     //先比大小 
    else if(a.s.size()==b.s.size()){        //大小相同則比較 起點位置,即出現早晚,因為乘上一個大數,一定是越小越早出現! 
        if(a.times<b.times) return 1;
    }
    return 0;
}

下面是我的醜程式碼,具體見註釋~

#include<bits/stdc++.h>
using namespace std;
map<string,int>mp; 
typedef struct node{
    string s;
    int times;
}node;
node ans[100001];
int cmp(node a,node b){
    if(a.s.size()>b.s.size()) return 1;     //先比大小 
    else if(a.s.size()==b.s.size()){        //大小相同則比較 起點位置,即出現早晚,因為乘上一個大數,一定是越小越早出現! 
        if(a.times<b.times) return 1;
    }
    return 0;
}

int main(){
    int l;
    string target,temp;
    cin>>l>>target;
    for(int i=0;i<=target.size()-l;i++){
        for(int j=l;j<=target.size()-i;j++){
            temp.assign(target,i,j);
            if(mp[temp]==0){                //如果第一次出現初始化一個×大數的基底 ,離散化 
                mp[temp]=100000*i+1;
            }
            else{
                mp[temp]++;
            }
        }
    }
    int maxnumber=0;
    map<string,int>::iterator it;                   //map迭代器 
    for(it=mp.begin();it!=mp.end();it++){           //求出來出現最多的次數 
        maxnumber=max(maxnumber,(it->second)%100000);   //記得取模 
    }

    int pos=0;
    for(it=mp.begin();it!=mp.end();it++){           //將出現的次數最多的串資訊記錄下來 
        if(it->second%100000==maxnumber){
            ans[pos].s.assign(it->first);
            ans[pos++].times=it->second;
        }
    }
    sort(ans,ans+pos,cmp);                          //排序 
    cout<<ans[0].s<<endl;
    return 0;
}