cpp c++面试常考算法题汇总

THE LAST TIME

The last time, I have learned

希望看到的人,能够对他的学习、工作有帮助,同时也希望有能力的人可以一起来完善此文档,让它可以发挥出更大的价值。

手写c++的unique_ptr

实际的 std::unique_ptr 还包括更多的功能,例如自定义删除器、数组支持等

template <typename T>class unique_ptr {public:explicit unique_ptr(T* ptr = nullptr) : ptr_(ptr) {}~unique_ptr() { delete ptr_; }// 删除复制构造函数和复制赋值运算符unique_ptr(const unique_ptr&) = delete;unique_ptr& operator=(const unique_ptr&) =delete;  // 提供移动构造函数和移动赋值运算符unique_ptr(unique_ptr&&// other) noexcept : ptr_(other.ptr_) { other.ptr_ = nullptr; }unique_ptr& operator=(unique_ptr&& other) noexcept {    if (this != &other) {        delete ptr_;        ptr_ = other.ptr_;        other.ptr_ = nullptr;    }    return *this;}T* operator->() { return ptr_; }T& operator*() { return *ptr_; }private:T* ptr_;};

手写c++的shared_ptr

template <typename T>class tiny_shared_ptr {public:tiny_shared_ptr(T* ptr = nullptr) : _ptr(ptr), _count(new size_t(1)) {    if (_ptr == nullptr) {        *_count = 0;    }}tiny_shared_ptr(const tiny_shared_ptr<T>& other) : _ptr(other._ptr), _count(other._count) {    if (_ptr) {        (*_count)++;    }}tiny_shared_ptr<T>& operator=(const tiny_shared_ptr<T>& other) {    if (this != &other) {        release_source();        _ptr = other._ptr;        _count = other._count;        if (_ptr) {            (*_count)++;        }    }    return *this;}T* operator->() const {    return _ptr;}int use_count() const {    return (_count ? *_count : 0);}~tiny_shared_ptr() {    release_source();}private:void release_source() {    if (_count) {        (*_count)--;        if (*_count == 0) {            delete _ptr;            delete _count;        }    }}T* _ptr;size_t* _count;};

手写c++的string

#include <iostream>#include <cstring>using namespace std;class MyString {public:MyString() : m_data(nullptr), m_size(0) {}MyString(const char* str) {    m_size = strlen(str);    m_data = new char[m_size + 1];    strcpy(m_data, str);}// 拷贝构造函数MyString(const MyString& other) {    m_size = other.m_size;    m_data = new char[m_size + 1];    strcpy(m_data, other.m_data);}// 移动构造函数MyString(MyString&& other) {    m_size = other.m_size;    m_data = other.m_data;    other.m_size = 0;    other.m_data = nullptr;}~MyString() {    if (m_data != nullptr) {        delete[] m_data;        m_data = nullptr;        m_size = 0;    }}MyString& operator=(const MyString& other) {    if (this != &other) {        if (m_data != nullptr) {            delete[] m_data;        }        m_size = other.m_size;        m_data = new char[m_size + 1];        strcpy(m_data, other.m_data);    }    return *this;}const char* c_str() const {    return m_data;}private:char* m_data;size_t m_size;};

手撕完美转发

/**   *  @brief  Forward an lvalue.   *  @return The parameter cast to the specified type.   *   *  This function is used to implement "perfect forwarding".   */template<typename _Tp>constexpr _Tp&&forward(typename std::remove_reference<_Tp>::type& __t) noexcept{ return static_cast<_Tp&&>(__t); }/**   *  @brief  Forward an rvalue.   *  @return The parameter cast to the specified type.   *   *  This function is used to implement "perfect forwarding".   */template<typename _Tp>constexpr _Tp&&forward(typename std::remove_reference<_Tp>::type&& __t) noexcept{    static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"    " substituting _Tp is an lvalue reference type");    return static_cast<_Tp&&>(__t);}

如何用c实现多态

  1. 定义基类的成员是函数指针,用于实现多态
  2. 派生类通过组合的方式(非继承)
  3. 派生类定义函数,构造时初始化对应函数到函数指针是上
  4. 通过同名的函数指针调用
#include <stdio.h>// 基类结构体struct Shape {void (*draw)(struct Shape *);  // 1. 成员是函数指针,用于实现多态};                                 // 派生类结构体 Circlestruct Circle {struct Shape base;  // 基类 2. 通过组合的方式int radius;};// 派生类结构体 Squarestruct Square {struct Shape base;  // 基类int side;};// 基类的 draw 函数实现void drawShape(struct Shape *shape) { printf("Drawing a shape\\n"); }// 派生类 Circle 的 draw 函数实现void drawCircle(struct Shape *shape) {    struct Circle *circle = (struct Circle *)shape;    printf("Drawing a circle with radius %d\\n", circle->radius);}// 派生类 Square 的 draw 函数实现void drawSquare(struct Shape *shape) {    struct Square *square = (struct Square *)shape;    printf("Drawing a square with side %d\\n", square->side);}int main() {    struct Circle circle = {{drawCircle}, 5};  // 3.定义并在类中初始化函数指针    struct Square square = {{drawSquare}, 4};    // 拿到各个结构体里的基类(作为一个成员变量)    struct Shape *shapes[] = {(struct Shape *)&circle,    (struct Shape *)&square};  // 4.通过指针调用    for (int i = 0; i < 2; i++) {        shapes[i]->draw(shapes[i]);    }    return 0;}

手撕vector

#include<bits/stdc++.h>using namespace std;template<typename T>class Allocator{public ://开辟释放内存T* allocate(int size){    return (T*)malloc(sizeof(T)*size);}T*deallocate(T* p){    free(p);}//构造析构void construct(T*p,const T &val){    new (p)T(val);//定位new}void destory(T*p){    p->~T();//调用析构函数}};template<typename T,typename Alloc=Allocator<T> >class vvecotr{public ://构造函数vvecotr(int size=20){//多少个元素。    alloc = new Allocator<T>();    _begin = alloc->allocate(size);//开辟多少个内存    _end = _begin+size;    _now = _begin; }//析构函数~vvecotr(){    free(_begin);    delete alloc;}//拷贝构造函数vvecotr(const vvecotr<T>&vec){//拷贝构造函数    alloc = new Allocator<T>();    int size = vec._end-vec._begin;    _begin = alloc->allocate(size);    _end = _begin+size;    _now=_begin;    T *p=vec._begin;    for(;p!=vec._now;p++,_now++){        alloc->construct(_now,*p);    }}//拷贝赋值构造函数vvecotr& operator=(const vvecotr<T>&vec){    if(this==&vec)return *this;    alloc->deallocate(_begin);    alloc = new Allocator<T>();    int size = vec._end-vec._begin;    _begin = alloc->allocate(size);    _end = _begin+size;    _now=_begin;    T *p=vec._begin;    for(;p!=vec._now;p++,_now++){        alloc->construct(_now,*p);    }    return *this;}vvecotr( vvecotr<T>&&vec){    cout<<"vvecotr( vvecotr<T>&&vec){"<<endl;    alloc = vec.alloc;    _begin=vec._begin;    _now = vec._now;    _end = vec._end;    vec._begin=vec._end=vec._now=nullptr;    vec.alloc=nullptr;}vvecotr & operator=( vvecotr<T>&&vec){    //不会出现自赋值    alloc = vec.alloc;    _begin=vec._begin;    _now = vec._now;    _end = vec._end;    vec._begin=vec._end=vec._now=nullptr;    vec.alloc=nullptr;    return *this;}void push_back(const T&val){    if(_now==_end){        resize();    }    alloc->construct(_now,val);    _now++;}void pop_back(){    if(_now != _begin){        alloc->destory(_now--);    }}T& operator[](int index){    return _begin[index];}bool empty(){    return _now==_begin;}int size(){    return _now-_begin;}void show(){    T*p =_begin;    while(p!=_now){        cout<< *p <<" ";        p++;    }    cout<<endl;}private:T* _begin ;T* _now;T* _end;Alloc *alloc;void resize(){    int size=_end-_begin;    T *p=alloc->allocate(size*2);    for(int i=0;i<size;i++){        p[i]=_begin[i];    }    alloc->deallocate(_begin);    _begin = p;    _now=p+size;    _end=p+size*2;}};vvecotr<int> get(){    vvecotr<int>vec(50);    for(int i=0;i<=5;i++)vec.push_back(i);    return vec;   }int main(){    vvecotr<int>vec(50);    for(int i=0;i<=15;i++)vec.push_back(i);    vec.show();           //测试右值拷贝构造    // vvecotr<int> a = std::move(vec);    // cout<<a.size()<<endl;    //测试右值拷贝赋值    // vvecotr<int>a;    // a=get();    // a.show();    return 0;}

手撕线程池

#include <iostream>#include <unistd.h>#include <queue>#include <vector>#include <thread>#include <mutex>#include <condition_variable>#include <functional>using namespace std;class ThreadPool {public:ThreadPool(size_t numThreads) : stop(false) {    for (size_t i = 0; i < numThreads; ++i) {        threads.emplace_back([this] {            while (true) {                std::function<void()> task;                {                    std::unique_lock<std::mutex> lock(queueMutex);  // lock                    condition.wait(lock, [this] { return stop || !tasks.empty(); });                    if (stop && tasks.empty()) {                        return;                    }                    task = std::move(tasks.front());                    tasks.pop();                }                task();            }        });    }}template <class F, class... Args>void enqueue(F&& f, Args&&... args) {    {        std::unique_lock<std::mutex> lock(queueMutex);        tasks.emplace([f, args...] { f(args...); });    }    condition.notify_one();  // wake up thread}~ThreadPool() {    {        std::unique_lock<std::mutex> lock(queueMutex);        stop = true;    }    condition.notify_all();    for (std::thread& thread : threads) {        thread.join();    }}private:std::vector<std::thread> threads;std::queue<std::function<void()>> tasks;std::mutex queueMutex;std::condition_variable condition;bool stop;};void printNumber(int num) {    sleep(5);  // ssimulate operational implementation    std::cout << num << std::endl;}int main() {    ThreadPool pool(4);    // submit tasks to thread pool    for (int i = 0; i < 10; ++i) {        pool.enqueue(printNumber, i);    }    // wait for all tasks to be completed    std::this_thread::sleep_for(std::chrono::seconds(1));    return 0;}

知识星球介绍 (cpp c++公认学习地)

里面服务也不会变,四个坚守目前:

1.每天都会看大家打卡内容,给出合理性建议。

2.大家如果需要简历指导,心里迷茫需要疏导都可以进行预约周六一对一辅导。

3.每周五晚上九点答疑聊天不会变。

4.进去星球了,后续如果有什么其他活动,服务,不收费不收费(可以合理赚钱就收取下星球费用,但是不割韭菜,保持初心)

(还有经历时间考验的独家私密资料)

全部评论

相关推荐

评论
1
5
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务