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. 成员是函数指针,用于实现多态
    }; // 派生类结构体 Circle
    struct Circle {
    struct Shape base; // 基类 2. 通过组合的方式
    int radius;
    };
    // 派生类结构体 Square
    struct 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.进去星球了,后续如果有什么其他活动,服务,不收费不收费(可以合理赚钱就收取下星球费用,但是不割韭菜,保持初心)

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

本文由mdnice多平台发布

相关推荐
两颗泡腾片7 小时前
C++提高编程学习--模板
c++·学习
你好!蒋韦杰-(烟雨平生)8 小时前
扫雷游戏C++
c++·单片机·游戏
monicaaaaan9 小时前
搜索二维矩阵Ⅱ C++
c++·线性代数·矩阵
zh_xuan10 小时前
duiLib 自定义资源目录
c++·ui
西红柿煎蛋10 小时前
C++11的可变参数模板 (Variadic Templates) 是如何工作的?如何使用递归解包一个参数包 (parameter pack)?
c++
源代码•宸10 小时前
深入浅出设计模式——创建型模式之原型模式 Prototype
c++·经验分享·设计模式·原型模式
晨曦学习日记11 小时前
Leetcode239:滑动窗口最大值,双端队列的实现!
数据结构·c++·算法
wait a minutes11 小时前
【c++】leetcode763 划分字母区间
开发语言·c++
菜还不练就废了11 小时前
7.25 C/C++蓝桥杯 |排序算法【下】
c语言·c++·排序算法
饭碗的彼岸one12 小时前
重生之我在10天内卷赢C++ - DAY 2
linux·开发语言·c++·笔记·算法·vim