秋招準備100天---10

設計模式


命令模式

本來可以將命令作爲一個抽象類,每個命令寫成一個具體類,然後客戶端直接調用具體命令類。
對於命令模式,大家可能 心存疑慮,明明是一個很簡單的調用邏輯,爲什麼要做如此的複雜,爲什麼不直接reciver的excute方法就可以實現功能?調用邏輯複雜,是爲了如果後續命令的增加, 能夠應對後續需求的變化。簡單的只是開發起來方便,但對後續的維護則是困難。除此之外,使用命令模式的另一個好處是可以實現命令記錄的功能,可以在調用者裏面使用一個數據結構來存儲執行過的命令對象,以此可以方便地知道剛剛執行過哪些命令,並可以在需要是恢復。並且可以在調用者中執行日誌的記錄。
命令模式
也就是說,invoker類是具體的執行者,command類是封裝命令,其中數據成員有invoker對象,receiver類是接收者類,client對象直接發送命令給receiver,這樣就把請求和具體實現分開了,而且最重要一點是,可以在receiver對象中,創建一個容器對象存儲命令,可以實現命令撤銷和重做。

命令模式解析

職責鏈模式

當一個請求發出時,低級處理者級別不夠,處理不了,就會把這個請求發給更高一級,所以這個請求就像在職責鏈上傳遞,直到有一個對象處理它。
Handler類:抽象處理類,包含自己類的對象,代表比此對象高一級對象
Concreate類:具體處理者類。可訪問它的後繼者,如果可以處理就處理,不能處理,就發給後繼者。

缺點:如果處理不當,請求會一直沒人處理,陷入死循環

中介者模式

中介者模式
當同事類之間存在相互影響的時候,也就是說,A類對象改變,B類對象也會改變,這時候用中介類來降低耦合。

享元模式

享元模式

訪問者模式

ToDo





算法

N皇后問題

輸出有多少可能組合。

bool isvalid(vector<int>& mat,int i,int j) {
    for(int k = 0; k < i;k++) {
        if (mat[k] == j || abs(i-k) == abs(j - mat[k]))
            return false;
    }
    return true;
}

int dfs(vector<int> mat,int i,int n) {
    int res = 0;
    if (i == n) {
        return 1;
    }
    for (int j = 0; j < n; j++) {
        if (isvalid(mat,i,j)) {
            mat[i] = j;
            res += dfs(mat,i+1,n);
//            mat[i] = -1;
        }
    }
    return res;
}


判斷兩個字符串是否爲變形詞

兩個字符串,s1,s2,如果兩個字符串包含的字符一樣,但是順序可能不一樣,就說這兩個是變形詞。
方法1:1.先判斷兩個字符串長度是否相同 2. 遍歷字符串,用數組保存每個字符出現的次數。 3.比較兩個數組每個Index的數值是否相同,出現相同的話就說明不是變形詞。

bool helper(string s1,string s2) {
    int m = s1.size(),n = s2.size();
    if (m != n)
        return false;
    vector<int> map1(128,0),map2(128,0);
    for (auto ch : s1) {
        map1[ch]++;
    }
    for (auto ch : s2)
        map2[ch]++;
    for (int i = 0; i < 128; i++) {
        if (map1[i] != map2[i])
            return false;
    }
    return true;
}

方法2:第一種方法,建立了兩個數組,其實只需要一個數組,記錄str1中的字符出現頻次,然後遍歷str2,當出現字符ch,map[ch]-1就可以,當出現<0的情況,返回false;

bool helper(string s1,string s2) {
    int m = s1.size(),n = s2.size();
    if (m != n)
        return false;
    vector<int> map1(128,0);
    for (auto ch : s1) {
        map1[ch]++;
    }
    for (int i = 0; i < s2.size(); i++) {
        map1[s2[i]]--;//主要是這裏變化
        if (map1[s2[i]] < 0)//判斷是否小於0
            return false;
    }
    return true;
}

字符串中數字子串的和

給定一個字符串,包括數字,字母,各種符號,當出現’-‘號時,看連續’-‘個數,奇數個數代表是負數,偶數個數代表正數,比如說,“A-1BC–12",那麼包含數字-1和12.
方法1:遍歷字符串,用一個flag標誌符號,當出現’-‘,就連續判斷之後的字符還是否爲’-’;當出現數字時,連續判斷之後出現的是否爲數字。當數字開始前的符號爲’-‘纔會用flag標誌。

int helper(string s) {
    int res = 0;
    int n = s.size();
    bool flag = true;
    for (int i = 0; i < n; i++) {
        if (s[i] >= '0' && s[i] <= '9') {
            if (i > 0 && s[i-1] != '-')
                flag = true;
            string temp = "";
            while ((i < n) && (s[i] >= '0' && s[i] <= '9')) {
                temp += s[i];
                i++;
            }
            i--;
            int t = stoi(temp);
            res += flag ? t : -t;
            flag = true;
        }
        if (s[i] == '-') {
            while ((i < n) && (s[i] == '-')) {
                flag = !flag;
                i++;
            }
            i--;
        }
    }

    return res;
}

方法2:從左導向右遍歷字符,準確收集數字,然後相加。關鍵點是怎麼把連續的數字組成一個數的過程,比起來上一個方法stoi好很多。

TODO
去掉字符串中連續出現k個’0‘的子串

字符串中會出現k個’0‘,去掉後,返回去掉後的字符串,比如”120000300“,k= 2,則處理後結果爲”1200003“。

方法1:

string helper(string s,int k) {
    int pos = 0,num = 0;
    int n = s.size();
    for (int i = 0; i < n; i++) {
        if (s[i] == '0') {
            num++;
        }
        else {
            if (num == k) {
                pos = pos - 2;
            }
            num = 0;
        }
        s[pos++] = s[i];
    }
    if (num == 2)
        pos = pos - 2;
    return s.substr(0,pos);
}
判斷兩個字符串是否爲旋轉字符串

s1 = “12345”,那麼s1的旋轉字符串有”23451“,”34512“,”45123“,”51234“,”12345“。所以給定兩個字符串s1,s2,判斷是不是互爲旋轉字符串。

方法1:把s2從第一個字符開始,每一個字符都放到最後一位,判斷兩個字符串是否相同。

bool isSame(string s1,string s2) {
    int m = s1.size(),n = s2.size();
    if (m != n)
        return false;
    string temp = s2;
    for (int i = 0; i < n; i++) {
        if (temp == s1)
            return true;
        temp = temp.substr(1,n-1) + temp[0];
    }
    return false;
}

方法2:另str= str2 + str2,然後判斷str中是否包含子串str1,因爲str包含所有旋轉子串。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章