字符串中找出连续最长的数字串,n个数里出现次数大于等于n/2的数

问答题

问答题1:以下代码输出的是?

#include 
int main(){
	char a[10] = { '1','2','3','4','5',\
		'6','7','8','9',0};
	int i = 8;
	char* p = a + i;
	printf("%s\n", p - 3);

	return 0;
}

提示:这道题靠的是字符串结尾的结束符,如果把左后一个字符 0换成'0',那么结果是未定义的,因为这并不是一个完整的字符串,一个完整的字符串后面一定要有一个反斜杠0表示字符串的结束.数字0也可以代表'\0'

问答题2:当一个类对象的生命周期结束后,关于调用析构函数的描述正确的是:

(A) 如果派生类没有定义析构函数,则只调用基类的析构函数
(B) 如果基类没有定义析构函数,则只调用派生类的析构函数
(C) 先调用派生类的析构函数,后调用基类的析构函数
(D) 先调用基类的析构函数,后调用派生类的析构函数

提示:析构函数就算没有定义,也会调用编译器默认的析构函数,析构函数和构造函数正好相反,首先构造基类对象,然后构造派生类对象,所以析构函数,先调用派生类的析构,再调用基类的析构函数.

问答题3:在函数中如何返回两个参数
c语言中可以利用结构体,数组,两个指针,或者两个全局变量,但是在 c++ 中是可以利用花括号{}直接返回两个参数的

问答题4:下面代码输出啥?

int main(){
	vector<int>array;
	array.push_back(100);
	array.push_back(300);
	array.push_back(300);
	array.push_back(300);
	array.push_back(300);
	array.push_back(500);
	vector<int>::iterator itor;
	for (itor = array.begin(); itor != array.end(); itor++{
		if (*itor == 300){
			itor = array.erase(itor);
		}
	}
	for (itor = array.begin(); itor != array.end(); itor++{
		cout << *itor << " ";
	}
	return 0}

提示:第一个 for() 循环的次数不是 6 次;因为在循环体中把数据抹除掉两个,这就导致只循环了三次就到了array.end 的位置,erase函数在删除当前元素的同时,自动指向下一个元素,然后才执行循环中的 ++ itor ,所以一共只有两个 300 被删除

答案:100 300 300 500

问答题5:下面关于一个类的静态成员描述中,不正确的是

(A) 静态成员变量可被该类的所有方法访问
(B) 该类的静态方法只能访问该类的静态成员函数
(C) 该类的静态数据成员变量的值不可修改
(D) 子类可以访问父类的静态成员
(E) 静态成员无多态特性

提示a:类的静态成员变量属于整个类,并不属于某个对象,它只存储了一份,供所有对象使用,当然也可以被所有方法访问.

示例

class A{
public:
	static void a_print(){
		cout <<"a_print调用"<<a<< endl;
	}
	void fun(){
		cout <<"fun()调用"<<a << endl;
	}
private:
	static int a;
};
int A::a = 1;

int main(){
	A a;
	a.a_print();
	a.fun();
	return 0;
}

编译可以通过.

提示b:该类的静态方法只能访问该类的静态成员函数或静态成员变量,不可以访问非静态成员,因为非静态成员是在对象创建之后才有的,但是静态成员在创建对象之前就有了,所以用静态访问非静态就相当于使用一个未定义的变量.

提示c:该类的静态数据成员变量的值可修改,不存在不安全的问题

class A{
public:
	static void a_print(){
		a = 2;
		cout <<"a_print调用"<<a<< endl;
	}
private:
	static int a;
};
int A::a = 1;

编译可以通过.

提示d:子类可以访问父类的静态成员,体现了类的继承性.

提示e:静态成员无多态性,由于 static 成员是属于类的,并不属于对象,但是多态的实现是由多个对象完成,比如基类指针指向子类的对象;另外 static 方法不允许被重写,而多态的必备条件之一就是要实现重写.

编程题

编程题1 :字符串中找出连续最长的数字串

读入一个字符串str,输出字符串str中的连续最长的数字串

输入描述:1个测试输入包含1个测试用例,一个字符串str,长度不超过 255

输出描述:在一行内输出 str 中里连续最长的数字串

输入 abcd12345ed125ss123456789
输出 123456789

提示:进行一次循环遍历,遇到数字就计算后面的字符串长度,并比较每次的长度,最后返回长度最长的字符串.

#include 
#include 
using namespace std;

int main(){
    string str,temp,res;
    int maxnum = 0;
    while(getline(cin,str)){
        for(int i=0;i<str.size();++i){
            temp = "";
            if(str[i]>='0' && str[i]<='9'){
                while(i<str.size() && str[i]<='9' && str[i]>='0'){
                    temp+=str[i];
                    ++i;
                }
            }
            if(temp.size()>res.size()){
                res = temp;
            }
        }
        cout<<res<<endl;
    }
    return 0;
}

代码简化…

#include 
#include 
using namespace std;

int main(){
    string str,temp,res;
    while(getline(cin,str)){
        for(int i=0;i<str.size()+1;++i){
            if(str[i]>='0' && str[i]<='9'){
                temp+=str[i];
            }else{
                if(temp.size()>res.size()){
                    res = temp;
                }else{
                    temp.clear();
                }
            }
        }
        cout<<res;
    }
    return 0;
}

注意字符串的长度比 size计算出来的大一个字节,所以在循环的时候要多执行一次,否则会提前退出,导致最后一次的数字字符串没有被计算在内.

编程题2 :输入n个整数,输出出现次数大于等于数组长度一半的数

方法一:首先进行排序,然后取中间数的,中间的数就是超过一半的数字,时间复杂度为 O(n * logn)

#include 
#include 
#include 
using namespace std;

int main(){
	int n;
	vector <int> vec;
	while (cin >> n){
		vec.push_back(n);
	}
	sort(vec.begin(), vec.end());	
	cout << vec[vec.size() / 2 - 1] << endl;
	return 0;
}

方法二:借助O(N)的辅助空间,使用复杂度可以降低到O(N),使用哈希映射的方法,然后遍历,如果记录的数大于等于一半,则输出当前数字.

#include 
#include 
using namespace std;

int main(){
    int n = 0;
    vector<int>vec;
    while(cin>>n){
        vec.push_back(n);
    }
    int array[50] = {0};
    for(int i = 0;i<vec.size();++i){
        array[vec[i]]++;
        if(array[vec[i]]>=(vec.size()/2)){
            cout<<vec[i]<<endl;
            break;
        }
    }
    return 0;
}

方法三(推介):只使用 O(N)的时间复杂度,也不借助任何辅助空间完成

提示:如果当前数字等于前面的数字,则记录次数+1,如果不等于则 -1,当计数次数的变量等于0时,把当前变量赋值给记录变量.把记录次数赋值为1,最后的记录变量一定是大于长度一半的变量.

#include 
#include 
using namespace std;

int main(){
    int n;
    vector<int>vec;
    while(cin>>n){
        vec.push_back(n);
    }
    int temp = vec[0];
    int time = 1;
    for(int i = 1;i<vec.size();++i){
        if(vec[i]==temp){
            time++;
        }else{
            time--;
        }
        if(time == 0){
            temp = vec[i];
            time++;
        }
    }
    cout<<temp<<endl;
    return 0;
}

你可能感兴趣的:(C++习题练习)