单选题:
1.以下程序的运行结果是() 【知识点遗忘】
int main(void)
{
printf("%s , %5.3s\n","computer","computer");
return 0;
}
A computer , puter
B computer , com
C computer , computer
D computer , compu.ter
我的回答: B (正确)
正确答案: B
输出:
COMPUTER, COM.
第一个是原样输出,没什么好说的。
第二个 %5.3s ,表示输出总长度是5,取字符串的前3个输出。所以输出COM,但是COM的长度又不够5,所以,在COM的前面补了2个空格,刚好是5。
2.若有定义语句: int a=10 ; double b=3.14 ; 则表达式 ‘A’+a+b 值的类型是() 【知识点遗忘】
A char
B int
C double
D float
我的回答: A (错误)
正确答案: C
因为按照类型大的与类型小的运算时,强制转换类型小的进行运算的规则,double < int < char,本题int转为double丢失的信息最少,因此结果是double类型。
类型转换的规则:
1. byte,short,char之间不会互相转换,他们三者在计算时首先会转换为int类型。
2.容量小的类型默认转换为容量大的数据类型;数据类型按容量大小排序为:byte,short,char->int->long->float->double。
3.容量大的数据类型转换为容量小的数据类型时,要加上强制转换符。
有多种类型的数据混合运算时,系统首先自动的将所有数据转换成容量最大的那一种数据类型,然后再进行计算.
3.在 c++ 语言中,对函数参数默认值描述正确的是() 【概念不清】
A 函数参数的默认值只能设定一个
B 一个函数的参数若有多个,则参数默认值的设定可以不连续
C 函数参数必须设定默认值
D 在设定了参数的默认值后,该参数后面定义的所有参数都必须设定默认值
我的回答: B (错误)
正确答案: D
C++语言中,允许在函数的说明或定义时,给一个或多个参数指定默认值。参数默认值必须从右向左定义,即在一个指定了默认值的参数的右边,不能出现没有指定默认值的参数。
4.选择表达式 11|10 的结果(本题数值均为十进制) 【审题不当】
A 11
B 10
C 8
D 2
我的回答: D (错误)
正确答案: A
一.【易混淆】数组指针与指针数组
下面到底哪个是数组指针,哪个是指针数组呢:
A) int *p1[10];
B) int (*p2)[10];
“[]”的优先级比“*”要高。p1 先与“[]”结合,构成一个数组的定义,数组名为p1,int 修饰的是数组的内容,即数组的每个元素。那我们现在就清楚,这是一个数组,其包含10 个指向int 类型数据的指针,即指针数组。
至于p2 就更好理解了,在这里“()”的优先级比“[]”高,“”号和p2 构成一个指针的定义,指针变量名为p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。p2 是一个指针,它指向一个包含10 个int 类型数据的数组,即数组指针。
二.【定义说明】
【内联函数】
内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内。
定 义 :内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。
动 机 :内联扩展是用来消除函数调用时的时间开销。
代码少、频繁调用的函数,适宜采用 inline 定义内联函数。
【赋值兼容规则】
**赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。**通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员,而且所有成员的访问控制属性也和基类完全相同。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。赋值兼容规则中所指的替代包括以下的情况:
● 派生类的对象可以赋值给基类对象。
● 派生类的对象可以初始化基类的引用。
● 派生类对象的地址可以赋给指向基类的指针。
编程题:
1.【组队竞赛】
牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。
【题目解析】:
队伍的水平值等于该队伍队员中第二高水平值,为了所有队伍的水平值总和最大的解法,也就是说每个队伍的第二个值是尽可能大的值。所以实际值把最大值放到最右边,最小是放到最左边。
【解题思路】:
● 本题的主要思路是贪心算法,贪心算法其实很简单,就是每次选值时都选当前能看到的局部最优解,所以这里的贪心就是保证每组的 第二个值取到能选择的最大值就可以,我们每次尽量取最大,但是最大的数不可能是中位数,所以退而求其次,取每组中第二大的。
● 排序,然后取下标为3n - 2,3n - 4 ,3n - 4… n+2,n位置的元素累加即可,相当下标为[0,n-1]的n个数做每组的最左边的数,剩下的2个数据两个为一组,大的值做最右边的数,次大的做中间值,这里就是把这个次大的值加起来。
● 例如现在排序后有 1 2 5 5 8 9 ,那么取 8 和 5相加等于 13。
【代码实现】
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
// IO型OJ可能会有多组测试用例,所以这里要持续接收输入多组测试用例。
int n;
while (cin >> n)
{
long long sum = 0;
vector<int> a;
a.resize(3*n);
for (int i = 0; i < (3 * n); i++)
{
cin >> a[i];
}
/* 排序,然后取下标为3n - 2,3n - 4 ,3n - 4... n+2,n位置的元素累加即可,
相当下标为[0,n-1]的n个数做每组的最左边的数,剩下的2个数据两个为一组,
大的值做最右边的数,次大的做中间值,这里就是把这个次大的值加起来 */
std::sort(a.begin(), a.end());
for (int i = n; i <= 3 * n - 2; i += 2)
{
sum += a[i];
}
cout << sum << endl;
system("pause");
}
}
2.【删除公共字符】
输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”
【题目解析】:
本题描述很简单,题目描述很清楚,读题即可。
【解题思路】:
本题如果使用传统的暴力查找方式,如判断第一个串的字符是否在第二个串中,在再挪动字符删除这个字符 的方式,效率为O(N^2),效率太低,很难让人满意。
- 将第二个字符串的字符都映射到一个hashtable数组中,用来判断一个字符在这个字符串。
- 判断一个字符在第二个字符串,不要使用删除,这样效率太低,因为每次删除都伴随数据挪动。这里可以考虑使用将不在字符添加到一个新字符串,最后返回新字符串。
【代码实现】
#include<iostream>
#include<string>
using namespace std;
int main()
{
// 注意这里不能使用cin接收,因为cin遇到空格就结束了。
// oj中IO输入字符串最好使用getline。
string str1, str2;
//cin>>str1;
//cin>>str2;
getline(cin, str1);
getline(cin, str2);
// 使用哈希映射思想先str2统计字符出现的次数
int hashtable[256] = { 0 };
for (size_t i = 0; i < str2.size(); ++i)
{
hashtable[str2[i]]++;
}
// 遍历str1,str1[i]映射hashtable对应位置为0,则表示这个字符在
// str2中没有出现过,则将他+=到ret。注意这里最好不要str1.erases(i)
// 因为边遍历,边erase,容易出错。
string ret;
for (size_t i = 0; i < str1.size(); ++i)
{
if (hashtable[str1[i]] == 0)
ret += str1[i];
}
cout << ret << endl;
return 0;
}