文章目录
一. 单选
1. 以下关于STL的描述中,()是错的
A STL容器是线程不安全的
B 当容量不够时,STL的一个典型实现是vector内部内存扩展方式为翻倍
C std::sort是稳定排序
D std::bitset不是一个STL容器
正确答案:C
在多线程中,需要手动上锁
有时是2倍有时是1.5倍
std::sort (insert+quick)——快排不稳定
bitset是位集合,不装类型是装二进制位
2. 以下STL的容器存放的数据,哪个肯定是排好序的()
A vector
B deque
C list
D map
正确答案:D
map——二叉排序树
3. 以下哪种STL容器中的对象是连续存储的()
A list
B vector
C map
D set
正确答案:B
map和set底层都是红黑树
4. STL中的哪种结构在增加成员时可能会引起原有成员的存储位置发生改变()
A map
B set
C list
D vector
正确答案:D
增加成员可能会导致扩容——开一块新空间然后将旧空间的内容拷贝下来,将指针指向新空间,释放旧空间——会导致原来存储的位置发生改变
向量,连续的内存空间
5. STL中的一级容器有:
A vector, deque, list, set, multiset, map, multimap.
B 序列容器,关联容器,容器适配器
C set, multiset, map, multimap.
D vector, deque, list.
正确答案:D
序列式容器——线性结构 vector list
关联式结构——非线性结构 map set
一级容器:数据类型不能是组合类型,是基本类型
6. STL中的unordered_map和priority_queue使用的底层数据结构分别是什么()
A rbtree,queue
B hashtable,heap
C rbtree,heap
D hashtable,queue
正确答案:B
六大组件:空间配置器、容器、算法、迭代器、仿函数、适配器
适配器:
stack、queue——deque
priority_queue——vector
map、set——rbtree
unordered_map——hash_map——hashtable
unordered_set——hash_set
默认是大堆
7. 下面关于迭代器失效的描述哪个是错误的()
A vector的插入操作不会导致迭代器失效
B map的插入操作不会导致迭代器失效
C vector的删除操作只会导致指向被删除元素及后面的迭代器失效
D map的删除操作只会导致指向被删除元素的迭代器失效
正确答案:A
迭代器失效:
插入 删除
8. 如何捕获异常可以使得代码通过编译?
class A {
public:
A(){}
};
void foo(){
throw new A;
}
A catch (A && x)
B catch (A * x)
C catch (A & x)
D 以上都是
正确答案:B
抛出的是A对象的类型——地址——A*
9.有如下程序段: 则程序输出:
#include <iostream>
using namespace std;
class A {
public:
~A() {
cout << "~A()";
}
};
class B{
public:
virtual ~B() {
cout << "~B()";
} }
; c
lass C: public A, public B {
public:
~C() {
cout << "~C()";
}
};
int main() {
C * c = new C;
B * b1 = dynamic_cast<B *>(c);
A * a2 = dynamic_cast<A *>(b1);
delete a2;
}
A C()B()~A()
B C()A()~B()
C A)B)都有可能
D 以上都不对
正确答案:D
动态转换,多态
不能正确释放,B与A没有继承关系
10.以下程序输出结果是____
class A
{
public:
A ():m_iVal(0){test();}
virtual void func() { std::cout<<m_iVal<<‘ ’;}
void test(){func();}
public:
int m_iVal;
};
class B : public A
{
public:
B(){test();}
virtual void func()
{
++m_iVal;
std::cout<<m_iVal<<‘ ’;
}
};
int main(int argc ,char* argv[])
{
A*p = new B;
p->test();
return 0;
}
A 1 0
B 0 1
C 0 1 2
D 2 1 0
E 不可预期
F 以上都不对
正确答案:C
多态
构造的时候: 0 1
调用:2
二. 编程
1. 统计每个月兔子的总数
有一种兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子。
例子:假设一只兔子第3个月出生,那么它第5个月开始会每个月生一只兔子。
一月的时候有一只兔子,假如兔子都不死,问第n个月的兔子总数为多少?
输入描述:
输入一个int型整数表示第n个月
输出描述:
输出对应的兔子总数
示例1:
输入
3
输
出
2
正确答案:
迭代法
#include <iostream>
using namespace std;
int Fib(int n)
{
if(n<=2)
return 1;
int f,f1 = 1,f2 = 1;
for(int i = 3;i<=n;i++)
{
f = f1+f2;
f1 = f2;
f2 = f;
}
return f;
}
int main() {
int month,sum = 0;
while(cin>>month)
{
sum = Fib(month);
cout<<sum<<endl;
}
return 0;
}
// 64 位输出请用 printf("%lld")
递归法
f(n) = 1 n<=2
f(n) = f(n-1)+f(n-2) n>2
#include <iostream>
using namespace std;
int Fib(int n)
{
if(n<=2)
return 1;
return Fib(n-1) + Fib(n-2);
}
int main() {
int month,sum = 0;
while(cin>>month)
{
sum = Fib(month);
cout<<sum<<endl;
}
return 0;
}
注意:n过大时可能会产生栈溢出
2. 字符串通配符
问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求
各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
:匹配0个或以上的字符(注:能被和?匹配的字符仅由英文字母和数字0到9组成,下同)
?:匹配1个字符
注意:匹配时不区分大小写。
输入:
通配符表达式;
一组字符串。
输出:
返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false
输入描述:
先输入一个带有通配符的字符串,再输入一个需要匹配的字符串
输出描述:
返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false
示例1:
输入
te?t*.*
txt12.xls
输出
false
示例2:
输入
z z
z
输
出
false
示例3:
输入
pq
pppq
输出
false
示例4:
输入
**Z
0QZz
输出
true
示例5:
输入
?Bc?
abcd
输出
true
示例6:
输入
h*?a
h#a
输出
false
说明
根据题目描述可知能被和?匹配的字符仅由英文字母和数字0到9组成,所以?不能匹配#,故输出false
示例7:
输入
ppqppq*pp***ppq
pppppppqppqqppqppppqqqppqppqpqqqppqpqpppqpppqpqqqpqqp
输出
false
正确答案:
#include <iostream>
#include <string>
using namespace std;
bool match(const char* pattern, const char *str)
{
//当前字符结束,返回true
if (*pattern == '\0' && *str == '\0')
return true;
//两个字符串有一个先结束,则返回false
if (*pattern == '\0' || *str == '\0')
return false;
if (*pattern == '?')
{
//新增用例,题目强调?只能够匹配数字和字母,所以增加新的判断
if(!isdigit(*str) && !isalpha(*str))
return false;
//遇到?号,匹配一个字符,跳过一个位置
return match(pattern + 1, str + 1);
} else if (*pattern == '*')
{
// 遇到*号,匹配0个(str不挪动),1个(两者都向前挪动一个字符)或多个(str向前挪动一个字符)
while(*pattern=='*')
{
pattern++;
} pattern--;
if(!isdigit(*str) && !isalpha(*str))
return match(pattern+1,str);
return match(pattern + 1, str) || match(pattern + 1, str + 1) || match(pattern, str+ 1);
}
else if (tolower(*pattern) == tolower(*str)) //忽略大小写
{
//如果当前字符相等,匹配下一个字符
return match(pattern + 1, str + 1);
}
return false;
}
int main()
{
string pattern, str;
while (cin >> pattern >> str)
{
bool ret = match(pattern.c_str(), str.c_str());
if (ret)
cout << "true" << endl;
else
cout << "false" << endl;
}
return 0;
}