大數據算法系列9:字符串匹配問題,海量字符串處理 一. 字符串匹配 二. 練習題 參考:

一. 字符串匹配

1.1 字符串匹配

字符串匹配:
字符串匹配在實際工作中經常遇到,但是我們經常使用的是編程語言自帶的功能,對底層瞭解不多。

1.2 字符串匹配算法

1.2.1 樸素算法

這個就很簡單的邏輯了,按照順序挨個去進行比對,如果第一個相同,就對比第二個,依次類推。


1.2.2 Rabin-Karp算法

類似求和取餘,如果餘數相同,再挨個比較一次,性能會優於樸素算法。


1.2.3 字符串匹配自動機

二. 練習題

2.1 面試題(第一個只出現一次的字符)

題目:

分析:
將每個字母出現的次數存入哈希表,然後在遍歷哈希表找只出現一次的字母即可。

代碼:

class Solution {
    public char firstUniqChar(String s) {
        //定義哈希集合存儲字符和出現數次
        HashMap<Character, Integer> map = new HashMap<>();
        //遍歷字符串記錄次數
        for(char c: s.toCharArray()){
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        //尋找只出現一次的字符
        for(char c: s.toCharArray()){
            if(map.get(c) == 1){
                return c;
            }
        }
        return ' ';
    }
}

2.2 POJ1200(字符串hash)

大意:
給定一個字符串,其中含有不同的字母數量爲m,現在求這個字符串中有多少個長度爲n且長的互不相同的字符子串 。舉個例子, n=3, m=4 ,字符串 "daababac". 長度爲3的不同的子串分別是: "daa"; "aab"; "aba"; "bab"; "bac". 因此, 答案是5.用set會超時。

分析:
把 三個的字符串存儲set即可,不過既然會超過時間,那麼就轉化爲對應的數值即可。

原值 映射值
a 0
b 1
c 2
d 3

代碼:

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
 
public class Main
{
    public static void main(String[] args) 
    {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int M = scan.nextInt();
        String str = scan.next();
        Set fuck = new HashSet();
        int len = str.length();
        for (int i = 0; i < len-N+1; i++) 
        {
            String tem = str.substring(i,i+N);
            fuck.add(tem);
        }
        System.out.println(fuck.size());
    }
 
}

2.3 Uva10006(Carmichael Number)

題目:

分析:
首先判斷 n 是不是素數,如果不是素數再 遍歷 1~n 之間的數,求出每一個 x^n,看是不是滿足條件,對於 xn 可以使用書上講的反覆平方法進行快速冪運算。

代碼:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
 
public class Main {
    
    private static long mod_pow(long x, long n, long mod){
        //快速冪
        //求x的n次方模mod
        if(n == 0) return 1;
        long res = mod_pow(x*x%mod, n/2, mod);
        if((n&1) > 0) res = res*x%mod;
        return res;
    }
    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        while(in.nextToken() != StreamTokenizer.TT_EOF){
            int n = (int)in.nval;
            if(n == 0) break;
            boolean flag = false;
            for(int i = 2; i<=Math.sqrt(n); i++){
                if(n % i == 0){
                    flag=true;
                    break;
                }
            }
            if(n == 2) flag=false;
            if(flag){
                for(int i = 2; i<n; i++){
                    if(mod_pow(i, n, n)%n != i){
                        flag = false;
                        break;
                    }
                }
            }
            if(flag){
                out.println("The number "+n+" is a Carmichael number.");
            }
            else out.println(n+" is normal.");
            out.flush();
            
        }
        
        
        
        
    }
 
}

參考:

  1. http://www.dataguru.cn/article-5747-1.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章