秋招准备100天---10

设计模式


命令模式

本来可以将命令作为一个抽象类,每个命令写成一个具体类,然后客户端直接调用具体命令类。
对于命令模式,大家可能 心存疑虑,明明是一个很简单的调用逻辑,为什么要做如此的复杂,为什么不直接reciver的excute方法就可以实现功能?调用逻辑复杂,是为了如果后续命令的增加, 能够应对后续需求的变化。简单的只是开发起来方便,但对后续的维护则是困难。除此之外,使用命令模式的另一个好处是可以实现命令记录的功能,可以在调用者里面使用一个数据结构来存储执行过的命令对象,以此可以方便地知道刚刚执行过哪些命令,并可以在需要是恢复。并且可以在调用者中执行日志的记录。
命令模式
也就是说,invoker类是具体的执行者,command类是封装命令,其中数据成员有invoker对象,receiver类是接收者类,client对象直接发送命令给receiver,这样就把请求和具体实现分开了,而且最重要一点是,可以在receiver对象中,创建一个容器对象存储命令,可以实现命令撤销和重做。

命令模式解析

职责链模式

当一个请求发出时,低级处理者级别不够,处理不了,就会把这个请求发给更高一级,所以这个请求就像在职责链上传递,直到有一个对象处理它。
Handler类:抽象处理类,包含自己类的对象,代表比此对象高一级对象
Concreate类:具体处理者类。可访问它的后继者,如果可以处理就处理,不能处理,就发给后继者。

缺点:如果处理不当,请求会一直没人处理,陷入死循环

中介者模式

中介者模式
当同事类之间存在相互影响的时候,也就是说,A类对象改变,B类对象也会改变,这时候用中介类来降低耦合。

享元模式

享元模式

访问者模式

ToDo





算法

N皇后问题

输出有多少可能组合。

bool isvalid(vector& 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 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 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 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包含所有旋转子串。

你可能感兴趣的:(100天)