华为4.10实习笔试题

题目一

题目描述:连续输入字符串,以空格键分割,输入字符串个数为n,请按长度为8拆分每个字符串后输出新的字符串数组,输出的字符串按照升序排列长度不是8整数的在后面补0,空字符串不处理。第一个输入的字符串为个数n,后面的为n个待处理的字符串。
测试用例:
输入:

2 abc 1234567890

输出:

12345678 90000000 abc00000

java版本

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class Huawei1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String str = sc.nextLine().trim();
        String[] strs = str.split(" ");
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            StringBuffer line = new StringBuffer(strs[i]);
            if (line.length() % 8 != 0) {
                line.append("0000000");
            }
            while (line.length() >= 8) {
                list.add(line.substring(0, 8));
                line = line.delete(0, 8);
            }
        }
        Collections.sort(list);
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
    }
}

题目二

题目描述:给定一个字符串,字符串包含数字、大小写字母以及括号(包括大括号,中括号,小括号),括号可以嵌套,即括号里面可以出现数字和括号。
按照如下规则对字符串进行展开,不需要考虑括号不成对的问题,不考虑数字后面没有括号的情况,即 2a2(b)不考虑。

  • 数字表示括号里的字符串重复的次数,展开后的字符串不包含括号
  • 将字符串进行逆序展开

测试用例:
输入:

abc3(A)

输出:

AAAcba

java版本:

import java.util.LinkedList;
import java.util.Scanner;

public class Huawei2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine().trim();
        // 第一个stack存放整个字符串,用于最后出栈输出
        LinkedList<Character> stack1 = new LinkedList<>();
        // 第二个stack存放每一个括号里面需要重复的内容
        LinkedList<Character> stack2 = new LinkedList<>();
        // 第三个stack存放括号前面的数字
        LinkedList<Character> stack3 = new LinkedList<>();
        for (int i = 0; i < str.length(); i++) {
            char temp = str.charAt(i);
            // 遇到a-z,A-Z,0-9以及 (,[,{ 三种左括号直接入栈
            if ((temp >= 'A' && temp <= 'Z') || (temp >= 'a' && temp <= 'z') || (temp >= '0' && temp <= '9')) {
                stack1.push(temp);
            }
            if (temp == '(' || temp == '[' || temp == '{') {
                stack1.push(temp);
            }
            // 遇到右括号弹出括号内容以及前面可能存在的数字
            if (temp == ')' || temp == ']' || temp == '}') {
                if (temp == ')') {
                    while (stack1.getFirst() != '(') {
                        stack2.push(stack1.pop());
                    }
                }
                if (temp == ']') {
                    while (stack1.getFirst() != '[') {
                        stack2.push(stack1.pop());
                    }
                }
                if (temp == '}') {
                    while (stack1.getFirst() != '{') {
                        stack2.push(stack1.pop());
                    }
                }
                // 弹出左边的括号
                stack1.pop();
                // 弹出括号内容写入StringBuffer
                StringBuffer sb = new StringBuffer();
                while (!stack2.isEmpty()) {
                    sb.append(stack2.pop());
                }
                // 弹出左括号前面的数字,一定要判断 stack1 是不是为空!!!
                while (!stack1.isEmpty() && stack1.getFirst() >= '0' && stack1.getFirst() <= '9') {
                    stack3.push(stack1.pop());
                }
                if (!stack3.isEmpty()) {
                    StringBuffer sbNum = new StringBuffer();
                    while (!stack3.isEmpty()) {
                        sbNum.append(stack3.pop());
                    }
                    int count = Integer.parseInt(sbNum.toString());
                    StringBuffer add = new StringBuffer();
                    for (int j = 0; j < count; j++) {
                        add.append(sb.toString());
                    }
                    // 将括号里的内容复制count次,再压入到主栈 stack1 中
                    for (int k = 0; k < add.length(); k++) {
                        stack1.push(add.charAt(k));
                    }
                } else {
                    // 如果出现左边括号前没有数字的情况,如abc2{{A}},则把之前弹出的括号内的内容重新压入栈中
                    for (int j = 0; j < sb.length(); j++) {
                        stack1.push(sb.charAt(j));
                    }
                }

            }
        }
        while (!stack1.isEmpty()) {
            System.out.print(stack1.pop());
        }
        System.out.println();
    }
}

考试时只通过了80%的测试用例,经过排查发现可能存在两处问题:

  1. 在从栈中弹出括号前面的数字时,需要先判断栈是否为空,避免遇到用例“3(AB)”时,出现NoSuchElementException(stack.getFirst())或NullPointerException(stack1.peekFirst())错误
    在这里插入图片描述
  2. 如果出现括号前面没有数字的情况,如abc2((ABC)),应该先判断有没有读到数字,如果没有则将之前弹出的括号里的内容再次压入到栈 stack1 中。
    在这里插入图片描述 在这里插入图片描述

题目三

题目描述:在N*M的地图上,每个点的海拔不同,从当前位置只能访问上下左右四个点且是没有访问过的点,此外下一步选择的点的海拔必须大于当前点。求从点A到点B一共有多少条路径,输出路数总数取余 1 0 9 10^9 109。左上角的坐标为(0,0),右下角的坐标为(N-1,M-1)
测试用例:
输入:第一行为地图大小,下面n行为每个点的海拔,最后一行前两个为A坐标(x,y),后两个为B坐标(z,v)

4 5
0 1 0 0 0
0 2 3 0 0
0 0 4 5 0
0 0 7 6 0
0 1 3 2

输出:

2

java版本:使用回溯法,递归求解,代码没有测试过,遇到复杂地图可能会超时

import java.util.Scanner;

public class Huawei3 {
    public int find(int[][] pos, int[] B, int i, int j, int n, int m) {
        if (i >= 0 && i < n && j >= 0 && j < m && i == B[0] && j == B[1]) {
            return 1;
        }
        int a = 0, b = 0, c = 0, d = 0;
        if (i >= 0 && i < n && j >= 0 && j < m && i + 1 < n && pos[i + 1][j] > pos[i][j]) {
            a = find(pos, B, i + 1, j, n, m);
        }
        if (i >= 0 && i < n && j >= 0 && j < m && i - 1 >= 0 && pos[i - 1][j] > pos[i][j]) {
            b = find(pos, B, i - 1, j, n, m);
        }
        if (i >= 0 && i < n && j >= 0 && j < m && j + 1 < m && pos[i][j + 1] > pos[i][j]) {
            c = find(pos, B, i, j + 1, n, m);
        }
        if (i >= 0 && i < n && j >= 0 && j < m && j - 1 >= 0 && pos[i][j - 1] > pos[i][j]) {
            d = find(pos, B, i, j - 1, n, m);
        }
        return a + b + c + d;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[][] pos = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                pos[i][j] = sc.nextInt();
            }
        }
        int[] A = new int[2];
        int[] B = new int[2];
        A[0] = sc.nextInt();
        A[1] = sc.nextInt();
        B[0] = sc.nextInt();
        B[1] = sc.nextInt();
        Huawei3 ob = new Huawei3();
        int count = ob.find(pos, B, A[0], A[1], n, m);
        System.out.println(count);
    }
}

第二种思路:使用迭代的方式,太晚了,待写。。。。

在这里插入代码片
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值