华为机考108题(c++)(70-80)

HJ70 矩阵乘法计算量估算

描述

矩阵乘法的运算量与矩阵乘法的顺序强相关。
例如:

A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵

计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。

编写程序计算不同的计算顺序需要进行的乘法次数。

数据范围:矩阵个数:1≤n≤15 ,行列数:1≤rowi​,coli​≤100 ,保证给出的字符串表示的计算顺序唯一

进阶:时间复杂度:O(n) ,空间复杂度:O(n)

输入描述:

输入多行,先输入要计算乘法的矩阵个数n,每个矩阵的行数,列数,总共2n的数,最后输入要计算的法则
计算的法则为一个字符串,仅由左右括号和大写字母('A'~'Z')组成,保证括号是匹配的且输入合法!

输出描述:

输出需要进行的乘法次数

方法一:栈方法

#include <iostream>
#include <vector>
#include <stack>

using namespace std;

int main() {
    int n;
    while(cin >> n) {
        string rule;
        vector<pair<int, int>> matrix;
        for (int i = 0; i < n; ++i) {//输入n个矩阵的行数和列数
            pair<int, int> temp;
            cin >> temp.first >> temp.second;
            matrix.push_back(temp);
        }
        cin >> rule;//输入计算法则
        stack<pair<int, int>> stk;
        int ans = 0, k = 0;
        for (int i = 0; i < rule.size(); ++i) {//遍历一遍计算法则
            if (rule[i] == ')') {//当为右括号时从栈中取出两个矩阵计算
                pair<int, int> y = stk.top();
                stk.pop();
                pair<int, int> x = stk.top();
                stk.pop();
                ans += x.first * x.second * y.second;//计算量
                pair<int, int> temp(x.first, y.second);//结果矩阵的大小
                stk.push(temp);
            } else if(rule[i] != '('){
                stk.push(matrix[k]);//当前为字母时,矩阵进栈
                k++;
            }
        }
        cout << ans <<endl;
    }
    return 0;
}

 方法二:递归

#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<map>

using namespace std;

map<char, pair<int, int> > matrix;//矩阵和大小之间的映射
int count;//计算量

pair<int, int> compute(string str){
    stack<pair<int, int> > stk; //记录尚未计算的矩阵
    str = str.substr(1, str.size()-2);//去掉首位的两个括号
    for(int i = 0; i < str.size();i++){
        if(str[i] == '('){ //如果是左括号,需要递归计算
            int layer = 0; 
            int j = i;
            while(j <= str.size()){//找到和当前左括号匹配的右括号
                if(str[j] == '('){
                    layer++;
                }else if(str[j] == ')'){
                    layer--;
                }
                if(layer == 0){
                    break;
                }
                j++;
            }
            pair<int, int> res = compute(str.substr(i, j - i + 1));//递归计算括号中的部分
            i = j ;//从括号后面的内容继续遍历
            if(stk.empty()){ //如果stk为空,表示当前得到的矩阵是第一个矩阵,需要存下,等待下一个矩阵计算
                stk.push(res);
            }else{ //若stk不为空,需要计算
                pair<int, int> temp = stk.top();
                stk.pop();
                count += temp.first * temp.second * res.second;
                stk.push(make_pair(temp.first,res.second));//更新栈中的值
            }
        }else if(isupper(str[i])){ //如果是矩阵的话
            if(stk.empty()){ //stk为空,进入到stk中
                stk.push(matrix[str[i]]);
            }else{ //如果栈不为空,需要计算
                pair<int, int> temp = stk.top();
                stk.pop();
                count += temp.first * temp.second * matrix[str[i]].second;
                stk.push(make_pair(temp.first,matrix[str[i]].second));//更新栈中的值
            }
        }
    }
    return stk.top(); //遍历一遍结束,返回当前计算的矩阵大小
}

int main(){
    int n;
    while(cin >> n){
        count = 0;
        string rule;
        char ch = 'A';
        for(int i = 0; i < n; i++){ //输入n个矩阵的行列数
            cin >> matrix[ch].first >> matrix[ch].second;
            ch++;
        }
        cin >> rule;  //输入运算法则
        stack<char> s; //记录代表矩阵的字符
        compute(rule);
        cout << count << endl;
    }
    return 0;
}


HJ71 字符串通配符

描述

问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(注:能被*和?匹配的字符仅由英文字母和数字0到9组成,下同)
?:匹配1个字符

注意:匹配时不区分大小写。

输入:
通配符表达式;
一组字符串。

输出:

返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false

数据范围:字符串长度:1≤s≤100 

进阶:时间复杂度:O(n^2),空间复杂度:O(n) 

输入描述:

先输入一个带有通配符的字符串,再输入一个需要匹配的字符串

输出描述:

返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false

方法一:动态规划

#include<string>
#include<iostream>
#include<vector>

using namespace std;

int match_string(string str,string pattern){
    int len1 = str.size();
    int len2 = pattern.size();
    vector<vector<int> > dp(len2+1,vector<int>(len1+1,0));
    //多加一行一列作为初始初值所用
    dp[0][0] = 1;//初始化
    for(int i=1;i <=len2;i++){
        char ch1 = pattern[i-1];
        设置每次循环的初值,即当星号不出现在首位时,匹配字符串的初值都为false
        dp[i][0] = dp[i-1][0]&&(ch1=='*');
        for(int j=1;j<=len1;j++){
            char ch2 = str[j-1];
        	if(ch1=='*'){
                dp[i][j]=dp[i-1][j]||dp[i][j-1]; //当匹配字符为*号时,可以匹配0个或者多个
            }else{
                if(isalpha(ch2)){//ch2为字母时,尝试是否能匹配
                    dp[i][j]=dp[i-1][j-1]&&(ch1=='?'||(ch2==ch1||ch2==(ch1+('A'-'a'))||ch2==(ch1-('A'-'a'))));
                }else if(isdigit(ch2)){//ch2为数字时,尝试是否能匹配
                    dp[i][j]=dp[i-1][j-1]&&(ch1=='?'||(ch1==ch2));
                }else {//ch2既不为字母也不为数字时,只有ch1和ch2相同才能匹配
                    dp[i][j]=dp[i-1][j-1]&&(ch1==ch2);
                }
            }

    	}
    }
    return dp[len2][len1];
}

int main(){
    string str1,str2;
    while(cin >> str1 >> str2){
       int flag =  match_string(str2,str1);
       if(flag){
           cout << "true" << endl;
       }else{
           cout << "false" << endl;
       }
    }
    
}

方法二:递归

#include<bits/stdc++.h>
using namespace std;

bool match(const char* s,const char* p){

    //两个字符串同时结束,返回true
    if((*p=='\0')&&(*s=='\0')){
        return true;
    }
     //两个字符串中有一个先结束,返回false
    if((*p=='\0')||(*s=='\0')){
        return false;
    }
    if(*p=='?'){//通配符为?时
        if(!isdigit(*s)&&!isalpha(*s)){//只能匹配数字或字母
            return false;
        }
        //匹配一个字符,从下一个位置开始继续匹配
        return match(s+1,p+1);
    }else if(*p=='*'){//通配符为!时
        while(*p=='*'){//多个*和一个*效果相同
            p++;
        }
        p--;
        //遇到*号,匹配0个(str+1,str1不用动),匹配1个(str和str1都往前移动1位),匹配多个(str不用动,str+1)
        return match(s,p+1) || match(s+1,p+1) ||  match(s+1,p);
    }else if(tolower(*p)==tolower(*s)){//不区分大小写
         //当前两字符相等,则进行下一个字符的匹配
        return match(s+1,p+1);
    }
    return false;//不满足上述三种情况,不匹配

}



int main(){
    string p,s;
    while(cin>>p>>s){
        bool res = match(s.c_str(),p.c_str());
        if(res){
            cout<<"true"<<endl;
        }else{
            cout<<"false"<<endl;
        }
    }
    return 0;
}

HJ72 百钱买百鸡问题

描述

公元五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?

现要求你打印出所有花一百元买一百只鸡的方式。

输入描述:

输入任何一个整数,即可运行程序。

输出描述:

 输出有数行,每行三个整数,分别代表鸡翁,母鸡,鸡雏的数量

方法一:数学办法

#include<iostream>
using namespace std;

//鸡翁、鸡母、鸡雏分别为x, y, z 三个变量。
//x+y+z=100
//5x+3y+z/3=100
//确定x即可算出y和z,若y和z为非负整数,则为有效结果,输出。

int main(){
     
    for(int x=0;x<=14;x++){//解方程,计算x的范围是[0,14],枚举x
        if((100-7*x)%4==0){
            int y=(100-7*x)/4;//求解y,z
            int z=100-x-y;
            printf("%d %d %d\n",x,y,z);
        }
    }
    return 0;
}

方法二: 暴力法

#include<iostream>
using namespace std;
 
int main(){
    for(int i = 0; i <= 20; i++) {
        for(int j = 0; j <= 33; j++) {
            for(int k = 0; k <= 100; k++){ //遍历所有可能的公鸡、母鸡、小鸡取值
                if(i + j + k == 100 && 5 * i + 3 * j + double(k) / 3 == 100) {//鸡的总数等于100,且总共花了100元
                    cout << i << " " << j << " " << k << endl;
                }
            }
        }
    }
    return 0;
}

HJ73 计算日期到天数转换

描述

根据输入的日期,计算是这一年的第几天。

保证年份为4位数且日期合法。

进阶:时间复杂度:O(n),空间复杂度:O(1)\

输入描述:

输入一行,每行空格分割,分别是年,月,日

输出描述:

输出是这一年的第几天

方法一:数组法

#include <iostream>
using namespace std;
int main(){
    int year,month,day;
    cin>>year>>month>>day;
    int count=0;//统计天数
    int monthday[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//monthday[i]表示第i月的天数
    if(year%400==0||(year%4==0&&year%100!=0)){//当前月份大于两个月且为闰年时,二月有29天
        monthday[2]=29;
    }
    for(int i=1;i<=month-1;i++){//统计到当前月份的天数
      count=count+monthday[i];
    }
    count=count+day;//加上当前月的天数
    cout<<count;
}

 方法二:

#include<iostream>
#include<string>

using namespace std;

int main(){
    int year,month,day;
    int res;
    int flag=0;
    int num[12]={31,59,90, 120, 151, 181, 212, 243, 273, 304, 334, 365};//num[i]表示第i+1个月结束后的天数
    while(cin>>year>>month>>day){
        if(year%4==0 && year%100!=0){//如果是闰年
            flag=1;
        }
        if(month<=2){
            if(month == 1){
                res = day;
            }else{
                res = num[0] + day;
            }
        }else{//超过2月就要考虑是否为闰年了
            res=num[month-2]+day+flag;
        }
        flag=0;
        cout<<res<<endl;
    }
}

 HJ74 参数解析

描述

在命令行输入如下命令:

xcopy /s c:\\ d:\\e,

各个参数如下:

参数1:命令字xcopy

参数2:字符串/s

参数3:字符串c:\\

参数4: 字符串d:\\e

请编写一个参数解析程序,实现将命令行各个参数解析出来。

解析规则:

1.参数分隔符为空格
2.对于用""包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s "C:\\program files" "d:\"时,参数仍然是4个,第3个参数应该是字符串C:\\program files,而不是C:\\program,注意输出参数时,需要将""去掉,引号不存在嵌套情况。
3.参数不定长

4.输入由用例保证,不会出现不符合要求的输入

数据范围:字符串长度:1≤s≤1000 

进阶:时间复杂度:O(n) ,空间复杂度:O(n) 

输入描述:

输入一行字符串,可以有空格

输出描述:

输出参数个数,分解后的参数,每个参数都独占一行

方法一:字符连接

#include<iostream>
#include<string>
#include<vector>
using namespace std;

int main(){
    string s;
    while(getline(cin, s)){
        vector<string> output;
        string temp = "";
        bool flag = false; //记录是否进入引号中
        for(int i = 0; i < s.length(); i++){
            if(flag){ //如果在引号中
                if(s[i] != '\"') //遇到非引号都添加为字符串
                    temp += s[i];
                else flag = false; //否则设置出引号
            }else{ //如果不在引号中
                if(s[i] == ' '){ //遇到空格隔断
                    output.push_back(temp); 
                    temp = "";
                }else if(s[i] == '\"') //遇到引号设置为进入引号
                    flag = true; 
                else //其余添加进字符串
                    temp += s[i];
            }
        }
        output.push_back(temp); //最后一段
        cout << output.size() << endl; //输出参数个数
        for(int i = 0; i < output.size(); i++)
            cout << output[i] << endl;
    }
    return 0;
}

 方法二:字符串截取

#include<iostream>
#include<string>
#include<vector>
using namespace std;

int main(){
    string s;
    while(getline(cin, s)){
        vector<string> output;
        int p = 0;
        bool flag = false; //记录是否进入引号中
        for(int i = 0; i < s.length(); i++){
            if(s[i] == '\"'){ //遇到引号
                if(!flag) //第一个引号
                    flag = true;
                else{ //第二个引号
                    flag = false;
                    output.push_back(s.substr(p, i - p)); //截取字符串加入
                }
                p = i + 1;
            } else if(s[i] == ' ' && !flag){ //遇到引号外的空格
                if(i != p)  //非空字符串
                    output.push_back(s.substr(p, i - p)); //截取字符串加入
                p = i + 1;
            } else if(i == s.length() - 1) //最后一个参数字符串
                output.push_back(s.substr(p, i - p + 1));
        }
        cout << output.size() << endl; //输出参数个数
        for(int i = 0; i < output.size(); i++)
            cout << output[i] << endl;
    }
    return 0;
}

 HJ75 公共子串计算

描述

给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。

注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。

数据范围:字符串长度:1≤s≤150 

进阶:时间复杂度:O(n^3),空间复杂度:O(n)

输入描述:

输入两个只包含小写字母的字符串

输出描述:

输出一个整数,代表最大公共子串的长度

方法一:枚举法

#include<iostream>
#include<string>
#include<math.h>

using namespace std;

int main(){
    string a,b;
    while(cin>>a>>b){//输入两个字符串
      int maxLen=0;
      for(int i=0;i<a.size();i++){
          for(int j=i;j<a.size();j++){
              string temp=a.substr(i,j-i+1);//temp为a的子串
              if(int(b.find(temp))<0){//若temp在b中没有出现,跳出当前循环,从下一个位置i开始找子串
                  break;
              }else if(maxLen<temp.size()){//找到了更长的公共子串
                  maxLen=temp.size();
              }
          }
      }
        cout<<maxLen<<endl;
    }
    return 0;
}


 方法二:动态规划

#include <iostream>
#include <vector>

using namespace std;

int main(){
    string a,b;
    while (cin >> a >> b)
    {
        int maxLen = 0;
        vector<vector<int>> dp(b.size()+1,vector<int>(a.size()+1,0));//动态数组,dp[i][j]表示b以第i个字符结尾,a以第j个字符结尾的公共子串的长度
        for (int i = 1; i <= b.size(); ++i){
            for (int j = 1; j <= a.size(); ++j){
                if (b[i - 1] == a[j - 1]) {//b中第i个字符和a中第j个字符相同
                    dp[i][j] = dp[i - 1][j - 1] + 1;//前一个长度加一
                }else {
                    dp[i][j] = 0;//如果第i个字符和第j个字符不同,则以他们结尾的子串不可能相同
                }
                if (maxLen < dp[i][j]) {//更新最大值
                    maxLen = dp[i][j];
                }
            }
        }
        cout << maxLen << endl;
    }
    return 0;
}

HJ76 尼科彻斯定理

描述

验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。

例如:

1^3=1

2^3=3+5

3^3=7+9+11

4^3=13+15+17+19

输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。

数据范围:1≤m≤100 

进阶:时间复杂度:O(m) ,空间复杂度:O(1)

输入描述:

输入一个int整数

输出描述:

输出分解后的string

方法一:遍历查找

#include<iostream>
#include<string>
using namespace std;

int main(){
    int m;
    while(cin >> m){
        int pow = m * m * m; //先获取三次方的值
        for(int i = 1; i < pow; i += 2){ //从1开始找到pow
            if(m * i + m * (m - 1) == pow){ //比较等差数列和与三次幂是否相等
                cout << i; //相等开始输出连续m个数字
                for(int j = 1; j < m; j++)
                    cout << '+' << i + 2 * j;
                cout << endl;
                break;
            }
        }
    }
    return 0;
}

方法二:数学规律

#include<iostream>
#include<string>
using namespace std;

int main(){
    int m;
    while(cin >> m){
        int odd = m * m - (m - 1); //根据公式获取起点奇数
        cout << odd;
        for(int i = 1; i < m; i++) //遍历后续m-1个奇数
            cout << '+' << odd + 2 * i; //输出
        cout << endl;
    }
    return 0;
}

HJ77 火车进站

描述

给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号,火车站只有一个方向进出,同时停靠在火车站的列车中,只有后进站的出站了,先进站的才能出站。

要求输出所有火车出站的方案,以字典序排序输出。

数据范围:1≤n≤10 

进阶:时间复杂度:O(n!) ,空间复杂度:O(n)

输入描述:

第一行输入一个正整数N(0 < N <= 10),第二行包括N个正整数,范围为1到10。

输出描述:

输出以字典序从小到大排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample。

方法一:全排列+栈

#include<iostream>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;

bool check(vector<int>& order, vector<int>& out){ //根据进来的顺序检查有无这种出去的顺序
    stack<int> s;
    int j = 0; //out数组的下标
    for(int i = 0; i < order.size(); i++){
        s.push(order[i]); //每次火车入栈
        while(!s.empty() && s.top() == out[j]){ //如果刚好栈顶等于输出,就全部出栈
            s.pop();
            j++;
        }
    }
    return s.empty();
}

int main(){
    int n;
    while(cin >> n){
        vector<vector<int> > output;
        vector<int> nums(n); //记录所有的数字
        vector<int> order(n); //记录数字进来的顺序
        for(int i = 0; i < n; i++){
            cin >> nums[i];
            order[i] = nums[i];
        }
        sort(nums.begin(), nums.end()); //对数字按照字典序排序
        do{
            output.push_back(nums);
        }while(next_permutation(nums.begin(), nums.end())); //获取全排列
        for(int i = 0; i < output.size(); i++){ 
            if(check(order, output[i])){ //检查每一种排列输出的可能性
                for(int j = 0; j < n; j++)
                    cout << output[i][j] << " ";
                cout << endl;
            }
        }
    }
    return 0;
}

方法二:dfs+回溯

#include<iostream>
#include<set>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;

void dfs(vector<int>& nums, stack<int> s, vector<int> temp, set<vector<int>>& output, int index, int& n){
    if(temp.size() == n){ //该情况结果已经完成
        output.insert(temp);
        return;
    }
    for(int i = 0; i < 2; i++){ //每次两个操作
        if(i == 0 && !s.empty()){ //要么从栈出弹出一个输出
            int num = s.top();
            s.pop();
            temp.push_back(num);
            dfs(nums, s, temp, output, index, n); //继续递归
            s.push(num); //回溯
            temp.pop_back(); 
        }else if(i == 1 && index < n){ //要么从数组中拿出一个加入栈中
            int num = nums[index];
            s.push(num);
            index++;
            dfs(nums, s, temp, output, index, n); //继续递归
            index--; //回溯
            s.pop();
        }
    }
}

int main(){
    int n;
    while(cin >> n){
        vector<int> nums(n);
        for(int i = 0; i < n; i++)
            cin >> nums[i];
        set<vector<int> > output;
        stack<int> s;
        vector<int> temp; //记录某一种情况的输出结果
        s.push(nums[0]); // 默认第一辆车都要先进去
        dfs(nums, s, temp, output, 1, n); //dfs找到全排列
        for(auto iter = output.begin(); iter != output.end(); iter++){ //遍历集合
            for(int i = 0; i < n; i++) //输出集合中每一个数组
                cout << (*iter)[i] << " ";
            cout << endl;
        }
    }
    return 0;
}

HJ80 整型数组合并

描述

题目标题:

将两个整型数组按照升序合并,并且过滤掉重复数组元素。

输出时相邻两数之间没有空格。

输入描述:

输入说明,按下列顺序输入:
1 输入第一个数组的个数
2 输入第一个数组的数值
3 输入第二个数组的个数
4 输入第二个数组的数值

输出描述:

输出合并之后的数组

方法一:hash + 排序

#include <bits/stdc++.h>

using namespace std;
vector<int> arr;
int n, m;

int main() {
	while (cin >> n) {           //多组测试数据
		arr.clear();
        //输入与合并两个数组
		for (int i = 1; i <= n; i ++ ) {
			int x; cin >> x;
			arr.push_back(x);
		}
		cin >> m;
		for (int i = 1; i <= m; i ++ ) {
			int x; cin >> x;
			arr.push_back(x);
		}
        //对合并数组升序排序
		sort(arr.begin(), arr.end());
		map<int, int> st;
        vector<int> ans;
        //遍历并保存未标记元素
        for (int i = 0; i < arr.size(); i ++ ) {
            if (!st[arr[i]]) {
                st[arr[i]] = 1; //更新标记
                ans.push_back(arr[i]);
            }
        }
        for (int i = 0; i < ans.size(); i ++ ) cout << ans[i];
        cout << "\n";
	}
		
	return 0;
} 

方法二:直接使用stl函数

#include <bits/stdc++.h>

using namespace std;
vector<int> arr;
int n, m;

int main() {
	while (cin >> n) {           //多组测试数据
		arr.clear();
        //输入与合并两个数组
		for (int i = 1; i <= n; i ++ ) {
			int x; cin >> x;
			arr.push_back(x);
		}
		cin >> m;
		for (int i = 1; i <= m; i ++ ) {
			int x; cin >> x;
			arr.push_back(x);
		}
        //对合并数组升序排序
		sort(arr.begin(), arr.end());
        //去重
		arr.erase(unique(arr.begin(), arr.end()), arr.end());
        for (auto i : arr) cout << i;
        cout << "\n";
	}
		
	return 0;
} 
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. 虚函数是可以[New一个对象的时候要根据虚函数的函数体来填虚表;而内联函数没有函数体,只是在预编译阶段展开]内联的,这样就可以减少函数调用的开销,提高效率(错误) 2. 一个类里可以同时存在[同一个类里无论什么函数都不能函数名和参数完全一样]参数和函数名都相同的虚函数与静态函数(错误) 3. 父类的析构函数是非虚的,但是子类的析构函数是虚的,delete子类指针(指向该子类对象)[特殊情况,参见5],会调用父类的析构函数(正确)//任何情况下删除子类都会调用到父类的析构函数 4.对于下面的类CA,sizeof(CA) = _B_: A. 4 B. 8 C. 12 D. 16 class CA { public: CA(); virtual ~CA(); //因为有虚函数,所以会有4个字节的虚表指针 private: int m_iTime; //成员变量4个字节 public: int GetTime(); int SetTime(int iTime); }; 5.下面这段程序,打印结果是_A_: A. 1 B. 2 C. 3 D. 以上都不对 int g_iCount = 0; class CParent { public: CParent() {} ~CParent() {g_iCount += 1;} }; class CSon : public CParent { public: CSon() {} ~CSon() {g_iCount += 2;} }; main() { CParent* p = new CSon(); delete p[由于p被声明成父类指针,并且父类和子类的析构函数都非虚,因此delete操作只能根据p指针声明的类型来调用父类的析构函数]; std::cout << g_iCount << std::endl; } 6.请问下面这段程序的输出结果是_A_: A. 2,1, B. 2,2, C. 1,1, D. 1,2, class CParent { public: CParent() {} virtual ~CParent() {} public: virtual void Print() { std::cout << "1,"; }; }; class CSon : public CParent { public: CSon() {}; virtual ~CSon() {}; public: void Print() { std::cout << "2,"; }; }; void Test1(CParent& oParent[这里是引用了一个外部对象,该对象的虚表不会发生变化]) {oParent.Print();} void Test2(CParent oParent[这里会在栈空间内重新构造一个CParent类的对象,如果传入实参的类型与CParent不同则虚表会发生变化]) {oParent.Print();} main() { CSon * p = new CSon(); Test1(*p); //这里只是一个引用 Test2(*p); //这里会在栈空间重新构造Cparent类对象 delete p; } 7.请问下面这段程序的输出结果是_D_: A. 2,1, B. 2,2, C. 1,1, D. 1,2, class CParent { public: CParent() {} virtual ~CParent() {} public: void Print(){ std::cout << "1," ; }; }; class CSon : public CParent { public: CSon() {} virtual ~CSon() {} public: void Print(){ std::cout << "2,"; }; }; main() { CSon oSon; CParent * pParent = &oSon; CSon * pSon = &oSon; pParent->Print(); pSon->Print();[由于父类和子类的Print函数都非虚,所以根据指针类型决定调用关系] } 8.请问下面这段程序的输出结果是_C_: A. 2,1, B. 2,2, C. 1,2, D. 1,1, class CParent { public: CParent() {Print();} virtual ~CParent() {} public: virtual void Print(){ std::cout << "1,"; } }; class CSon : public CParent { public: CSon() {Print();} virtual ~CSon() {} public: void Print(){ std::cout << "2,"; } }; main() { CParent * pParent = new CSon()[类的构造过程遵循压栈原则,构造过程中虚表尚未建立成功,是静态调用虚函数]; delete pParent; } 9.请问下面这段程序的输出结果是_D_: A. 2,2, B. 2, C. 输出结果不确定 D. 以上都不对 class CParent { public: CParent() {Print();[构造子类对象时调用到父类的构造函数,但父类的Print函数是纯虚的,没有实现,所以这里的调用不成功,编译会出错]} virtual ~CParent() {} public: virtual void Print() = 0; }; class CSon : public CParent { public: CSon() {Print();} virtual ~CSon() {} public: void Print() { std::cout << "2,"; }; }; main() { CParent * pParent = new CSon(); delete pParent; } 10.请仔细阅读以下程序: class Base { public: virtual bool operator == (int iValue) { std::cout << "I am Base class !" << std::endl; return true; } virtual ~Base(){} }; class Derive: public Base { public: virtual bool operator == (int iValue) { std::cout << "I am Derive class !" << std::endl; return true; } virtual ~Derive(){} }; int main() { Derive derive; Base* pBase = &derive; Derive* pDerive = &derive; *pBase == 0; *pDerive == 0;[重载操作符声明为virtual使操作符产生多态性] return 0; } 程序的输出结果是_B_: A、I am Base class ! I am base class ! B、I am Derive class ! I am Derive class ! C、I am base class ! I am Derive class ! D、I am Derive class ! I am Base class !

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南叔先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值