2020-09-30

保存一下单例模式这块还有一些需要的代码:

  单例模式:
简单来说就是一个类只能构建一个对象的设计模式
单例设计模式就是一个类只能实例化出一个对象,不能实例化出多个对象,单例模式分为两种,一种是饿汉单例模式,是指在类创建的时候就已经实例化出了一个对象,好处是这个模式没有线程安全问题,坏处是浪费资源,不管之后有没有用到,都会先实例化一个对象,代码如下:
       还有一种是懒汉模式,顾名思义,当你需要用它的时候才去实例化对象,如果多个线程同时去实例化对象,那么产生的对象可能不唯一,所以存在线程安全的问题,避免这个线程安全的解决办法是用双检查锁(double checked locking)。
 
解释:
(线程实例化一个对象,然后线程结束后 , 另一个线程直接使用该对象 , 不会再重新创建 , 结束后调用析构函数)
1.要想让一个类只能构建一个对象,自然不能让它随便去做new操作,因此Signleton的构造方法是私有的。
 
2.instance是Singleton类的静态成员,也是我们的单例对象。它的初始值可以写成Null,也可以写成new Singleton()。至于其中的区别后来会做解释。
 
3.getInstance是获取单例对象的方法。
 
如果单例初始值是null,还未构建,则构建单例对象并返回。这个写法属于单例模式当中的 懒汉模式。
 
如果单例对象一开始就被new Singleton()主动构建,则不再需要判空操作,这种写法属于 饿汉模式
4 . 为了防止new Singleton被执行多次,因此在new操作之前加上Synchronized 同步锁,锁住整个类(注意,这里不能使用对象锁)。
 
5.进入Synchronized 临界区以后,还要再做一次判空。因为当两个线程同时访问的时候,线程A构建完对象,线程B也已经通过了最初的判空验证,不做第二次判空的话,线程B还是会再次构建instance对象。
 
 
工厂模式:
 
工厂模式:定义一个用于创建对象的接口 , 让子类去决定实例化哪个类,工厂方法使一个类的实例化延迟到其子类
(在工厂模式下 , 新增一个产品 , 必须要新增一个与之相对应的工厂类)
 
简单工厂:
简单工厂是工厂模式最简单的一种实现,对于不同产品的创建定义一个工厂类,将产品的类型作为参数传入到工厂的创建函数,根据类型分支选择不同的产品构造函数。
 
抽象工厂:
抽象工厂模式对工厂方法模式进行了更加一般化的描述。工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合,就是当具有多个抽象产品类型时,抽象工厂便可以派上用场。一个具体的工厂可以生产多个产品
抽象工厂是工厂模式的一个扩展。具体工厂类可以创建多个产品体系的对象,但是还是需要修改抽象工厂和具体工厂的代码 , 违反开闭原则
 
 
观察者模式:
是一种基于事件和响应的设计模式
当对象间有一对多的依赖关系时,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。
 
 
单例模式指的是一个类只能构建一个实例化对象,单例模式分为饿汉模式和懒汉模式。饿汉模式是说当类创建的时候就已经实例化对象了,好处是没有线程安全问题 , 坏处是浪费资源 ,不管后面有没有用到它,该对象已经创建
懒汉模式是指,当我们用到它的时候才会去创建类的实例化对象 , 如果多个线程同时去实例化对象 , 那么对象可能不唯一 ,这时候就存在线程安全问题。可以通过双检查锁来避免。
 
工厂模式,定义一个用于创建对象的接口。让子类去决定实例化哪个类。
每新增一个产品都要添加一个与之相对应的工厂类
 
简单工厂模式:对于不同产品的创建定义一个工厂类 , 将产品的类型作为参数传递到创建函数 , 根据类型的不同选择不同的产品构造函数
 
抽象工厂模式是工厂模式的一个扩展,具体工厂类可以创建多个产品体系的对象 , 但是需要修改抽象工厂和具体工厂的代码 , 违反开闭原则。
 
观察者模式:是一种基于事件和响应的设计模式
当对象间有一对多的依赖关系时 , 一个对象的状态发生改变 , 所有依赖于它的对象都会得到通知并自动更新。
 
 
 
 
 
堆排
#include <stdio.h>
#include <iostream>
using namespace std;
int h[101] , n;

void swap(int x , int y)//交换堆中俩个元素的值
{
    int t;
    t = h[x];
    h[x] = h[y];
    h[y] = t;
    return;
}
void siftdown(int i)//小顶堆
{
    int t , flag = 0;//flag用来标记是否需要向下调整
    while(i*2 <= n && flag == 0)
    {
        if(h[i] > h[i*2])
        {
            t = i*2;
        }
        else
        {
            t = i;
        }
        if(i*2+1 <= n)
        {
            if(h[t] > h[i*2+1])
            {
                t = i*2+1;
            }
        }
        if(t != i)
        {
            swap(t,i);
            i = t;
        }
        else
        {
            flag = 1;
        }
    }
    return;
}
//建立堆的函数
void creat()
{
    for(int i = n/2 ; i >= 1 ; i--)
    {
        siftdown(i);
    }
    return;
}
//删除最大的元素
int deletemax()//从小到大输出
{
    int t;
    t = h[1];//用一个临时变量记录堆顶点的值
    h[1] = h[n];//将堆的最后一个点的值赋给堆顶
    n--;//堆的元素减少1
    siftdown(1);//向下调整
    return t;
}
void heapsort()//堆排序  原数组  从大到小
{
    while(n>1)
    {
        swap(1,n);
        n--;
        siftdown(1);
    }
    return;
}
int main()
{
    int num;
    scanf("%d" , &num);
    for(int i = 1 ; i <= num ; i++)
    {
        scanf("%d" , &h[i]);
    }
    n = num;
    creat();//建堆
    //删除顶部元素 , 连续删除n次 , 也就是从大到小把数输出来

   // heapsort();
    for(int i = 1 ; i <= num ; i++)
    {
      printf("%d " , deletemax());
     //printf("%d " , h[i]);
    }

    return 0;
}

 

 
 
快排
#include <stdio.h>
int a[101] , n;
void quicksort(int left , int right)
{
    int i , j , t , temp;
    if(left > right) return;
    temp = a[left];
    i = left ;
    j = right;
    while(i != j)
    {
        while(a[j] >= temp && i < j)
        j--;
        while(a[i] <= temp && i < j)
        i++;
        if(i < j)
        {
            t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
    }
    a[left] = a[i];
    a[i] = temp;
    quicksort(left , i-1);
    quicksort(i+1,right);
    return;
}
int main()
{
    scanf("%d" , &n);
    for(int i = 1 ; i <= n ; i++)
    {
        scanf("%d" , &a[i]);
    }
    quicksort(1,n);
    for(int i = 1 ; i <= n ; i++)
    {
        printf("%d " , a[i]);
    }
    return 0;
}

 

死锁例子
#include <iostream>
#include <thread>
#include <mutex>
#include <windows.h>
using namespace std;
mutex mt1 , mt2;
static int data1 = 1, data2 = 1;
void a2()
{
    mt2.lock();
    data1++;
    cout <<"a2 " << data1 << endl;
    Sleep(1);
    mt1.lock();
    data2++;
    mt1.unlock();
    mt2.unlock();
}
void a1()
{
    mt1.lock();
    data2++;
    cout << "a1  "<< data2 << endl;
    Sleep(1);
    mt2.lock();
    data1++;
    mt2.unlock();
    mt1.unlock();
}
int main()
{
    thread t2(a2);
    thread t1(a1);
    t1.join();
    t2.join();
    
    return 0;
}

 

智能指针
 
 
//shared_ptr 的循环引用:俩个对象互相使用一个shared_ptr成员变量指向对方, 导致引用计数失效
#include <iostream>
#include <memory>//包含智能指针的头文件
using namespace std;
class B;
class A{
    public:
        shared_ptr<B> pb;
        ~A(){
            cout << "kill A \n";
        }
};

class B{
    public:
        shared_ptr<A> pa;
        ~B(){
            cout << "kill B\n";
        }
};
int make()
{
    shared_ptr<A> sa(new A());
    shared_ptr<B> sb(new B());

    if(sa && sb)
    {
        sa->pb = sb;
        sb->pa = sa;
    }
    cout << " sa use count : " << sa.use_count()<<endl;
    return 0;
}

 

kmp
class Solution{
public:
    
    int strStr(string haystack , string needle){
        if(needle == "") return 0;
        int len = haystack.length();
        int len2 = needle.length();
        vector<int>Next(len2+6,0);
        getNext(Next, needle , len2);
        int i = 0 , j = 0;
        while(i < len && j < len2){
            if(j == -1 || haystack[i] == needle[j])
            {
                i++;
                j++;
            }
            else
            {
                j = Next[j];
            }
        }
        if(j == len2)
        {
            return i-len2;
        }
        else
        {
            return -1;
        }
        
    }
    void getNext(vector<int> &Next ,string &needle ,int len2){
        Next[0] = -1;
        int i = 0  , j = -1;
        while(i < len2)
        {
            if(j == -1 || needle[i] == needle[j])
            {
                ++i;
                ++j;
                Next[i] = j;
            }
            else
            {
                j = Next[j];
            }
        }
    }
};

 

匈牙利
#include <iostream>
using namespace std;
const int maxn = 1e4+8;
int M , N ;
int Map[maxn][maxn];
int p[maxn];
bool vis[maxn];
bool match(int i)
{
    for(int j = 1 ; j <= N ; j++)
    {
        if(Map[i][j] && !vis[j])
        {
            vis[j] = true;
            if(p[j] == 0|| match(p[j]))//这里递归
            {
                p[j] = i;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    int cnt = 0;
    cin >> N >> M;
    for(int i = 1 ; i <= M ; i++)
    {
        memset(vis,0,sizeof(vis));//重点,每次都要置为0 , 进入递归
        if(match(i))cnt++;
    }
    cout << cnt << endl;
    return 0;
}

 

 
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值