C++进制转换(dl)


进制转换

class Solution {
public:
    /**
     * 进制转换
     * @param M int整型 给定整数
     * @param N int整型 转换到的进制
     * @return string字符串
     */
     string solve(int M, int N) {
        // write code here
        if(M == 0) return "0";//如果M=0就直接返回
        bool flag = false;//记录是不是负数
        if(M < 0){
            //如果是负数flag=true,M 取相反数
            flag = true;
            M = -M;
        }
        string res = "";//返回最终的结果
        string jz = "0123456789ABCDEF";//对应进制的某一位
        while(M != 0){//就对应转换为N进制的逆序样子
            res += jz[M % N];
            M /= N;
        }
        reverse(res.begin(),res.end());//逆序一下才是对应的N进制
        if(flag) res.insert(0,"-");//如果是负数就在头位置插入一个-号
        return res;
    }
};

手撕个环形队列

#pragma once
#include <iostream>
#include <assert.h>
using namespace std;

template<typename T>
class MyQueue2 {
public:
	MyQueue2(int _capacity = 10);
	MyQueue2(const MyQueue2<T>& que);
	MyQueue2<T>& operator=(const MyQueue2<T>& que);
	~MyQueue2();

	void push(T val);
	void pop();
	int size();
	int capcity();
	bool empty();
	T front();
	T back();
private:
	T* queue;
	int front_index;
	int back_index;
	int capacity;
	int qsize;
};

template<typename T>
MyQueue2<T>::MyQueue2(int _capacity) :front_index(0),back_index(0),capacity(_capacity){
	this->queue = new T[_capacity];
	assert(this->queue != nullptr);
}
template<typename T>
MyQueue2<T>::MyQueue2(const MyQueue2<T>& que):front_index(que.front_index),back_index(que.back_index),capacity(que.capacity) {
	this->queue = new T[capacity];
	this->qsize = que.qsize;
	int j = que.front_index;
	for (int i = 0; i < que.qsize; i++) {
		this->queue[i] = que.queue[(j++) % que.capacity];
	}
}
template<typename T>
MyQueue2<T>& MyQueue2<T>::operator=(const MyQueue2<T>& que) {
	if (que != this) {
		delete[] queue;
		this->capacity = que.capacity;
		this->front_index = que.front_index;
		this->back_index = que.back_index;
		this->qsize = que.qsize;
		this->queue = new T[capacity];
		int j = que.front_index;
		for (int i = 0; i < que.qsize; i++) {
			this->queue[i] = que.queue[(j++) % que.capacity];
		}
	}
	return *this;
}
template<typename T>
MyQueue2<T>::~MyQueue2() {
	delete[] this->queue;
}
template<typename T>
void MyQueue2<T>::push(T val) {
	if (this->qsize < this->capacity) {
		this->queue[this->back_index] = val;
		this->back_index = (this->back_index + 1) % this->capacity;
		this->qsize++;
	}
	else {
		T* newqueue = new T[2 * capacity];
		for (int i = 0; i < this->qsize; i++) {
			newqueue[i] = this->queue[(this->front_index++) % this->capacity];
		}
		delete[] this->queue;
		this->queue = newqueue;
		this->front_index = 0;
		this->back_index = this->qsize;
		this->queue[this->back_index] = val;
		this->back_index = (this->back_index + 1) % this->capacity;
		this->qsize++;
		this->capacity *= 2;
	}
}
template<typename T>
void MyQueue2<T>::pop() {
	if (this->qsize != 0) {
		this->front_index = (this->front_index + 1) % this->capacity;
		this->qsize--;
	}
	else
		cout << "empty queue!" << endl;
}
template<typename T>
int MyQueue2<T>::size() {
	return this->qsize;
}
template<typename T>
int MyQueue2<T>::capcity() {
	return this->capacity;
}
template<typename T>
bool MyQueue2<T>::empty() {
	return this->qsize == 0;
}
template<typename T>
T MyQueue2<T>::front() {
	if (this->qsize) {
		return this->queue[this->front_index];
	}
	else {
		cout << "empty queue!" << endl;
	}
}
template<typename T>
T MyQueue2<T>::back() {
	if (this->qsize) {
		return this -> queue[this->back_index - 1];
	}
	else {
		cout << "empty queue!" << endl;
	}
}

手撕大根堆

#pragma once
#include<iostream>
#include<vector>
using namespace std;

class MyBigHeap {
public:
	void push(int val) {
		heap.push_back(val);
		int c = heap.size() - 1;
		int p = (c - 1) / 2;
		while (c > 0) {
			if (heap[c] > heap[p]) {
				swap(heap[c], heap[p]);
				c = p;
				p = (c - 1) / 2;
			}
			else
				break;
		}
	}
	void pop() {
		heap[0] = heap.back();
		heap.pop_back();
		int i = 0, j = i * 2 + 1;
		while (j < heap.size()) {
			if (j < heap.size() - 1 && heap[j] < heap[j + 1]) {
				j++;
			}
			if (heap[i] < heap[j]) {
				swap(heap[i], heap[j]);
				i = j;
				j = 2 * i + 1;
			}
			else
				break;
		}
	}
	int top() {
		return heap[0];
	}
private:
	vector<int> heap;
};

手撕个vector

#pragma once
#include <iostream>
#include <assert.h>
#include<algorithm>
using namespace std;

template<typename T>
class MyVector {
public:
	MyVector(int _vcapacity = 10);
	MyVector(const MyVector<T>& mv);
	MyVector<T>& operator=(const MyVector<T>& mv);
	~MyVector();

	void push_back(T val);
	void pop_back();
	int size();
	int capacity();
	void insert(int index, T val);
	T operator[](int index);
private:
	T* array;
	int vsize;
	int vcapacity;
};

template<typename T>
MyVector<T>::MyVector(int _vcapacity) :vcapacity(_vcapacity), vsize(0) {
	this->array = new T[_vcapacity];
}
template<typename T>
MyVector<T>::MyVector(const MyVector<T>& mv) {
	delete[] this->array;
	this->vcapacity = mv.vcapacity;
	this->vsize = mv.vsize;
	this->array = new T[mv.vcapacity];
	for (int i = 0; i < mv.vsize; i++) {
		this->array[i] = mv.array[i];
	}
}
template<typename T>
MyVector<T>& MyVector<T>::operator=(const MyVector<T>& mv) {
	if (mv != this) {
		delete[] this->array;
		this->vcapacity = mv.vcapacity;
		this->vsize = mv.vsize;
		this->array = new T[mv.vcapacity];
		for (int i = 0; i < mv.vsize; i++) {
			this->array[i] = mv.array[i];
		}
	}
	return *this;
}
template<typename T>
MyVector<T>::~MyVector() {
	delete[] this->array;
}
template<typename T>
void MyVector<T>::push_back(T val) {
	if (this->vsize < vcapacity) {
		this->array[this->vsize] = val;
		this->vsize++;
	}
	else {
		T* newarray = new T[2 * this->vcapacity];
		for (int i = 0; i < this->vsize; i++) {
			newarray[i] = this->array[i];
		}
		delete[] this->array;
		this->array = newarray;
		this->vcapacity = 2 * this->vcapacity;
		array[vsize] = val;
		this->vsize++;
	}
}
template<typename T>
void MyVector<T>::pop_back() {
	this->vsize--;
}
template<typename T>
int MyVector<T>::size() {
	return this->vsize;
}
template<typename T>
int MyVector<T>::capacity() {
	return this->vcapacity;
}
template<typename T>
void MyVector<T>::insert(int index, T val) {
	if (this->vsize == this->vcapacity)
	{
		T* temp = new T[2*this->vcapacity];
		copy(array, array + vcapacity, temp);
		delete[] array;
		this->array = temp;
		this->vcapacity *= 2;
	}
	copy_backward(array + index, array + this->vsize, array + this->vsize + 1);
	this->array[index] = val;
	this->vsize++;
}
template<typename T>
T MyVector<T>::operator[](int index) {
	assert(index < this->vsize);
	return array[index];
}


手撕个memcpy

void memcpy(void *pDst ,void *pSrc ,size_t length)
{
	char *dst=static_cast<char*>(pDst);    //转换成char*
	char *src=static_cast<char*>(pSrc);
	
	if ((src==nullptr)||(dst==nullptr))   //判断是否为野指针
	{
		/* code */
		return;
	}
	
	//分段讨论,判断dst和区间(src,src+length)的位置关系
	//地址不重叠,
	//(1)dst<src,dst在src前面,此时即便dst尾部和src的头部有部分重叠也无所谓,只需要从src的头部复制到尾部即可
	//(2)dst>src+length,只需要从src的头部复制到尾部即可
	if (dst<src || dst>src+length)    
	{
		/* code */
		for (int i = 0; i < length; ++i)
		{
			/* code */
			*dst++=*src++;
		}
	}
	else     //地址重叠,(3)src <= dst <= src+length,此时需要从尾部开始复制
	{
		dst=dst+length-1;   //定位到尾部
		src=src+length-1;
		for (int i = length; i >=0 ; i--)  //从尾部开始复制
		{
			/* code */
			dst[i]=src[i];
		}
	}

}

手撸哈希表(基于容器实现版)

#pragma once
#include<iostream>
#include<vector>
#include<string>
#include<list>
using namespace std;

template<typename T>
class Myhash{
public:
	Myhash():h_size(0), h_capacity(10),hash_array(10) {}
	void insert(T val);
	void print();
	int index(T val);
	void rehash(int _capacity);
	int capacity();
	int size();
private:
	vector<list<int>> hash_array;
	int h_size;
	int h_capacity;
};

template<typename T>
int Myhash<T>::index(T val) {
	return val % this->h_capacity;
}
template<typename T>
void Myhash<T>::insert(T val) {
	int i = this->index(val);
	this->hash_array[i].push_back(val);
	this->h_size++;
	if (this->hash_array[i].size() > 5) {
		this->rehash(this->h_capacity * 2);
	}
}
template<typename T>
void Myhash<T>::rehash(int _capacity) {
	this->h_capacity = _capacity;
	vector<list<T>> temp(_capacity);
	for (auto l : this->hash_array) {
		for (auto n : l) {
			int temp_index = this->index(n);
			temp[temp_index].push_back(n);
		}
	}
	this->hash_array = temp;
}

template<typename T>
void Myhash<T>::print() {
	for (auto l : this->hash_array) {
		for (auto n : l) {
			cout << n << " ";
		}
		cout << endl;
	}
}

template<typename T>
int Myhash<T>::capacity() {
	return this->h_capacity;
}

template<typename T>
int Myhash<T>::size() {
	return this->h_size;
}
#include"hash.h"

int main() {
	Myhash<int> h;
	for (int i = 0; i < 40; i++) {
		h.insert(i);
	}
	h.print();
	cout << "size: " << h.size() << " capacity: " << h.capacity() << endl;
	for (int i = 40; i < 85; i++) {
		h.insert(i);
	}
	h.print();
	cout << "size: " << h.size() << " capacity: " << h.capacity() << endl;
	Myhash<int> h1 = h;
	h.print();
	cout << "size: " << h.size() << " capacity: " << h.capacity() << endl;
	Myhash<int> h2(h);
	h.print();
	cout << "size: " << h.size() << " capacity: " << h.capacity() << endl;
	return 0;
}

手撕share_ptr

#pragma once

template<class T>
class SharedPointer
{
public:
    //默认构造函数,内部指针,未指向任何资源,引用计数为0,因为它未与任何资源绑定
    SharedPointer() :m_refCount(nullptr), m_pointer(nullptr) {}

    //构造函数,初始化时,指向一个已经分配好的资源
    SharedPointer(T* adoptTarget) :m_refCount(nullptr), m_pointer(adoptTarget)
    {
        addReference();
    }

    //构造函数,使用其它对象创建新对象
    SharedPointer(const SharedPointer<T>& copy)
        :m_refCount(copy.m_refCount), m_pointer(copy.m_pointer)
    {
        addReference();
    }

    //析构函数,引用计数递减,当为0时,释放资源
    virtual ~SharedPointer()
    {
        removeReference();
    }

    //赋值操作
    //当左值被赋值时,表明它不再指向所指的资源,故引用计数减一
    //之后,它指向了新的资源,所以对应这个资源的引用计数加一
    SharedPointer<T>& operator=(const SharedPointer<T>& that)
    {
        if (this != &that)
        {
            removeReference();
            this->m_pointer = that.m_pointer;
            this->m_refCount = that.m_refCount;
            addReference();
        }
        return *this;
    }

    //判断是否指向同一个资源
    bool operator==(const SharedPointer<T>& other)
    {
        return m_pointer == other.m_pointer;
    }
    bool operator!=(const SharedPointer<T>& other)
    {
        return !operator==(other);
    }

    //指针解引用
    T& operator*() const
    {
        return *m_pointer;
    }
    //调用所知对象的公共成员
    T* operator->() const
    {
        return m_pointer;
    }

    //获取引用计数个数
    int GetReferenceCount() const
    {
        if (m_refCount)
        {
            return *m_refCount;
        }
        else
        {
            return -1;
        }
    }

protected:
    //当为nullpter时,创建引用计数资源,并初始化为1
    //否则,引用计数加1。
    void addReference()
    {
        if (m_refCount)
        {
            (*m_refCount)++;
        }
        else
        {
            m_refCount = new int(0);
            *m_refCount = 1;
        }
    }

    //引用计数减一,当变为0时,释放所有资源
    void removeReference()
    {
        if (m_refCount)
        {
            (*m_refCount)--;
            if (*m_refCount == 0)
            {
                delete m_refCount;
                delete m_pointer;
                m_refCount = 0;
                m_pointer = 0;
            }
        }
    }

private:
    int* m_refCount;
    T* m_pointer;
};

调用验证:

#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include "SharedPointer.h"

using namespace std;
class MyClass
{
public:
    ~MyClass()
    {
        cout << "释放MyClass(" << _id << ")\n";
    }

    MyClass(int i) :_id(i)
    {

    }

    void Print() const
    {
        cout << "MyClass(" << _id << ")" << endl;
    }
private:
    int _id;
};

int main()
{
    {
        MyClass* px = new MyClass(1);

        SharedPointer<MyClass> ap(px);
        SharedPointer<MyClass> bp = ap;
        SharedPointer<MyClass> cp;

        cout << "ap的引用计数(2): "
            << ap.GetReferenceCount() << endl;

        cout << "将ap赋值给cp\n";
        cp = ap;

        cout << "ap的引用计数(3): "
            << ap.GetReferenceCount() << endl;


        MyClass* qx = new MyClass(5);
        SharedPointer<MyClass> dp(qx);
        ap = dp;

        cout << "ap的引用计数(2): "
            << ap.GetReferenceCount() << endl;

        cout << "dp的引用计数(2): "
            << dp.GetReferenceCount() << endl;

        //"像指针一样使用智能指针"
        dp->Print();
        (*cp).Print();
    }

    cin.get();
}

手撕strlen

size_t strlen(const char* str) {
    if(str == NULL) {
        return 0;
    }
    const char* pc = str;
    while(*pc++ != '\0');
    return pc - str - 1;
}

手撕strcmp

int strcmp(const char* rhs, const char* lhs) {
    // 判空测试
    assert(rhs != NULL);
    assert(lhs != NULL);
    
    // 注意这里必须是 unsigned char
    // 表示的范围为 0 ~ 255
    // 如果是 char 的话, 范围是 -128 ~ 127, 这个范围用来比较字符串是不对的
    unsigned char c1, c2;
    while(1) {
        c1 = *rhs++;
        c2 = *lhs++;
        if(c1 != c2) {
            return c1 < c2 ? -1 : 1;
        }
        if(c1 == 0) {
            break;
        }
    }
    return 0;
}

手撕智能指针

#pragma once

template<class T>
class SharedPointer
{
public:
    //默认构造函数,内部指针,未指向任何资源,引用计数为0,因为它未与任何资源绑定
    SharedPointer() :m_refCount(nullptr), m_pointer(nullptr) {}

    //构造函数,初始化时,指向一个已经分配好的资源
    SharedPointer(T* adoptTarget) :m_refCount(nullptr), m_pointer(adoptTarget)
    {
        addReference();
    }

    //构造函数,使用其它对象创建新对象
    SharedPointer(const SharedPointer<T>& copy)
        :m_refCount(copy.m_refCount), m_pointer(copy.m_pointer)
    {
        addReference();
    }

    //析构函数,引用计数递减,当为0时,释放资源
    virtual ~SharedPointer()
    {
        removeReference();
    }

    //赋值操作
    //当左值被赋值时,表明它不再指向所指的资源,故引用计数减一
    //之后,它指向了新的资源,所以对应这个资源的引用计数加一
    SharedPointer<T>& operator=(const SharedPointer<T>& that)
    {
        if (this != &that)
        {
            removeReference();
            this->m_pointer = that.m_pointer;
            this->m_refCount = that.m_refCount;
            addReference();
        }
        return *this;
    }

    //判断是否指向同一个资源
    bool operator==(const SharedPointer<T>& other)
    {
        return m_pointer == other.m_pointer;
    }
    bool operator!=(const SharedPointer<T>& other)
    {
        return !operator==(other);
    }

    //指针解引用
    T& operator*() const
    {
        return *m_pointer;
    }
    //调用所知对象的公共成员
    T* operator->() const
    {
        return m_pointer;
    }

    //获取引用计数个数
    int GetReferenceCount() const
    {
        if (m_refCount)
        {
            return *m_refCount;
        }
        else
        {
            return -1;
        }
    }

protected:
    //当为nullpter时,创建引用计数资源,并初始化为1
    //否则,引用计数加1。
    void addReference()
    {
        if (m_refCount)
        {
            (*m_refCount)++;
        }
        else
        {
            m_refCount = new int(0);
            *m_refCount = 1;
        }
    }

    //引用计数减一,当变为0时,释放所有资源
    void removeReference()
    {
        if (m_refCount)
        {
            (*m_refCount)--;
            if (*m_refCount == 0)
            {
                delete m_refCount;
                delete m_pointer;
                m_refCount = 0;
                m_pointer = 0;
            }
        }
    }

private:
    int* m_refCount;
    T* m_pointer;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
VS2010中使用C++创建和使用DL.docx,文档加代码,全了。工程代码下载: 1.生成动态链接库(_declspec(dllexport)方式导出函数) 2.生成动态链接库(以.def文件(模块定义文件)方式导出函数) 3.以加载时动态链接方式调用DLL 4.以运行时动态链接方式调用DLL 5.以模块定义方式(.def文件)建立的动态链接库的调用 遇到的问题: 1.库导入的时候目录的问题。对应文中的问题1,后面有解释。 2.字符集的问题(是Unicode字符集还是多字节集),两种方案,一种修改字符集为多字节集,二是将字符串前面加 _T(""),文中问题2 3.不知道怎么通过模块定义文件方式生成DLL,通过看参考博客的代码找到了答案,主要修改头文件,和添加模块定义文件。 4.模块定义文件中的库文件名应和工程名一致。 DllMain函数 Windows在加载DLL时,需要一个入口函数,就像控制台程序需要main函数一样。有的时候,DLL并没有提供DllMain函数,应用程序也能成功引用DLL,这是因为Windows在找不到DllMain的时候,系统会从其它运行库中引入一个不做任何操作的默认DllMain函数版本,并不意味着DLL可以抛弃DllMain函数。 根据编写规范,Windows必须查找并执行DLL里的DllMain函数作为加载DLL的依据,它使得DLL得以保留在内存里。这个函数并不属于导出函数,而是DLL的内部函数,这就说明不能在客户端直接调用DllMain函数,DllMain函数是自动被调用的。 DllMain函数在DLL被加载和卸载时被调用,在单个线程启动和终止时,DllMain函数也被调用。参数ul_reason_for_call指明了调用DllMain的原因,有以下四种情况: DLL_PROCESS_ATTACH:当一个DLL被首次载入进程地址空间时,系统会调用该DLL的DllMain函数,传递的ul_reason_for_call参数值为DLL_PROCESS_ATTACH。这种情况只有首次映射DLL时才发生; DLL_THREAD_ATTACH:该通知告诉所有的DLL执行线程的初始化。当进程创建一个新的线程时,系统会查看进程地址空间中所有的DLL文件映射,之后用DLL_THREAD_ATTACH来调用DLL中的DllMain函数。要注意的是,系统不会为进程的主线程使用值DLL_THREAD_ATTACH来调用DLL中的DllMain函数; DLL_PROCESS_DETACH:当DLL从进程的地址空间解除映射时,参数ul_reason_for_call参数值为DLL_PROCESS_DETACH。当DLL处理DLL_PROCESS_DETACH时,DLL应该处理与进程相关的清理操作。如果进程的终结是因为系统中有某个线程调用了TerminateProcess来终结的,那么系统就不会用DLL_PROCESS_DETACH来调用DLL中的DllMain函数来执行进程的清理工作。这样就会造成数据丢失; DLL_THREAD_DETACH:该通知告诉所有的DLL执行线程的清理工作。注意的是如果线程的终结是使用TerminateThread来完成的,那么系统将不会使用值DLL_THREAD_DETACH来执行线程的清理工作,这也就是说可能会造成数据丢失,所以不要使用TerminateThread来终结线程。以上所有讲解在工程DLLMainDemo(工程下载)都有体现。 函数导出方式

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VioletEvergarden丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值