C++ STL和几道经典的面试题

2024-05-04 04:18
文章标签 c++ 面试题 经典 stl 几道

本文主要是介绍C++ STL和几道经典的面试题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

https://blog.csdn.net/dingyahui123/article/details/78644235

 

C++ STL 的实现:

1.vector:  底层数据结构为数组 ,支持快速随机访问。

2.list:    底层数据结构为双向链表,支持快速增删。

3.deque:  底层数据结构为一个中央控制器和多个缓冲区,详细见STL源码剖析P146,支持首尾(中间不能)快速增删,也支持随机访问。

4.stack :  底层一般用23实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时

5.queue:   底层一般用23实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时(stack和queue其实是适配器,而不叫容器,因为是对容器的再封装)

6.priority_queue: 的底层数据结构一般为vector为底层容器,堆heap为处理规则来管理底层容器实现

7.set:  底层数据结构为红黑树,有序,不重复。

8.multiset: 底层数据结构为红黑树,有序,可重复。

9.map:      底层数据结构为红黑树,有序,不重复。

10.multimap: 底层数据结构为红黑树,有序,可重复。

11.hash_set: 底层数据结构为hash表,无序,不重复。

12.hash_multiset: 底层数据结构为hash表,无序,可重复 。

13.hash_map :     底层数据结构为hash表,无序,不重复。

14.hash_multimap: 底层数据结构为hash表,无序,可重复。

1)不用算术运算符进行求和不使用算术运算求和那么只能考虑直接在二进制位上进行位运算,事实上利用异或运算(^)和与运算(&)就能完成加法运算要做的事情,其中异或运算完成相加但是不进位,而与运算计算出哪些地方需要进位,在通过左移运算(<<)就可以完成进位操作了。

    #include"iostream.h"
     
    int sum(int a,int b){
    if(b == 0) return a;  
            int c = a ^ b;  
            int d = (a & b) << 1;  
            return sum(c, d);}
    int main(){
     cout<<sum(12,13);
    return 0;  
    }


2)利用位运算中异或运算的特点,两个相同的数异或的结果一定是0,那么将a和b中的所有元素做一次异或运算,最终的结果就是b比a多出的那个元素的值

    #include"iostream.h"
    int find(int a[],int b[],int n){
        int c = 0;  
            for(int i = 0; i <n; i++) {  
                c ^= a[i] ^ b[i];  
            }  
            c ^= b[n];  
       return c;
    }
    int main(){
    int a[6]={1, 3, 2, -4, 10, 18};  
    int b[]= {3, 55, 1, 2, 10, -4, 18};
     cout<<find(a,b,6);
    return 0;
    }


3)题目:有一个已经排好序的数组,其中存在重复元素,请将重复元素删除掉,例如,A = [1, 1, 2, 2, 3],处理之后的数组应当为A = [1, 2, 3]。

    public: int remove(int &A[],int n){
        if(n==0)
        return 0;
        int index=0;
        for(int i=1;i<n;i++)
        {
            if(A[index]!=A[i])
            A[++index]=A[i];
        }
        index++;
        return index;
    }

在O(n)的时间复杂度内完成数组移动,如abcde,左移三位变为cdeab,如果数组长度为l,移动位数为n,如果n大于l的话相当于移动n%l位,如果用一般的循环移位时间复杂度为O(n×l),不能在规定的要求内完成,所以只能考虑在数组本身上下功夫,如abcde,移动3位,可以理解为剩下的前两位翻转,后3位翻转然后整个数组翻转,abcde->bacde->baedc->cdeab,这样就可以在O(n)等级的时间复杂度内完成操作。大致功能函数如下

    int reverse(int i,int j,int *array)
    {  
        for(;i>m;i++,m--)
            {
            temp = array[i];  
            array[i] = array[j];   
            array[j] = temp;
           }
    }
    int main()
    {
        int n;//移动的位数
        reserve(0,n-1,A);
        reserve(n,L-n-1,A);
        reserve(0,n-1,A);
    }  


4)F(M,N)求解不大于N的和是M的所有组合个数。使用递归求解组合个数。

    #include "iostream"
    using namespace std;
    int f(int m,int n)
    {
         if(m==1)
              return 1;
         if(n==1)
         {
              return 1;
         }
         if(m<n)
        {
           return f(m,m);
        }
       if (m==n)
       {
          return 1+f(m,n-1);
       }
       return f(m,n-1)+f(m-n,f(m-n,n));
    }
    int main()
    {
        cout<<f(3,3);
    }


5)打靶算法:靶环有10个环,那么当打中时分数可为1-10,如果未打中得分为0,也就是11种可能,比如现在求6枪50分的概率

    #include <iostream>  
    #include <time.h>     
    using namespace std;   
    int sum;  
    int all=0;
    int n;
    int store[10];   
    void Output()   
    {   
        for(int i = 9; i>=0; --i)   
        {   
           cout<<store[i]<<" ";
        }  
       cout<<endl;   
        ++sum;   
    }   
    void Cumput(int score, int num)   
    {   
       if(score < 0 || score > (num+1)*10 ) //次数为0~9  
          return;  
       if(num == 0)    
         {     
            store[num] = score;   
            Output();    
            for(int i = 9; i>=10-num; --i)   
        {   
           all+=store[i];
        }  
           if(all==score){
               n++;
               all=0;
           }
            return;   
         }   
       for(int i = 0; i <= 10; ++i)  
         {  
            store[num] = i;  
            Cumput(score - i, num - 1);  
            
         }  
    }  
    int main()  
     {       
    const  double  begin=(double)clock();      
    Cumput(50, 6);  
        const  double  end=(double)clock();    
        cout<<"总的可能数量:"<<sum<<" ."<<"得分可能数量:"<<n<<endl;  
        cout<<"用时:"<<end-begin<<endl;   
        cout<<"概率"<<double(n)/sum;
        return 0;  
      }
    ......................
    ......................
    0 0 0 10 10 10 10 8 2 0
    0 0 0 10 10 10 10 9 0 1
    0 0 0 10 10 10 10 9 1 0
    0 0 0 10 10 10 10 10 0 0
    总的可能数量:195195 .得分可能数量:3003
    用时:339931
    概率0.0153846

如果不用递归的思想,使用循环的方式的话,要打几枪需要写几层循环,虽然思路简单,如果是打是几十或上百那要写死了。
---------------------  
作者:刀客123  
来源:CSDN  
原文:https://blog.csdn.net/dingyahui123/article/details/78644235  
版权声明:本文为博主原创文章,转载请附上博文链接!

这篇关于C++ STL和几道经典的面试题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/958324

相关文章

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

C++11委托构造函数和继承构造函数的实现

《C++11委托构造函数和继承构造函数的实现》C++引入了委托构造函数和继承构造函数这两个重要的特性,本文主要介绍了C++11委托构造函数和继承构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、委托构造函数1.1 委托构造函数的定义与作用1.2 委托构造函数的语法1.3 委托构造函

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ