华为2018春招笔试题

华为2018春招笔试(3月21日)


题目一 最长数字字符串

给定一个字符串,输出字符串中最长的数字串,并把这个数字串的长度输出。

请一个在字符串中找出连续最长的数字串,并把这个串的长度返回;如果存在长度相同的连续数字串,返回最后一个连续数字串;

注意:数字串只需要是数字组成的就可以,并不要求顺序,比如数字串“1234”的长度就小于数字串“1359055”,如果没有数字,则返回空字符串(“”)而不是NULL!

输入描述:
一个字符串
输出描述:
输出最长的数字串,输出最长数字串个数;
中间以逗号(,)隔开;

示例1
输入
abcd12345ed125ss123058789
输出
123058789,9

备注:
1、如果存在长度相同的连续数字串,则输出最后一个连续数字串;
2、数字串只需要是数字组成的就可以,并不要求顺序,比如数字串“1234”的长度就小于数字串“1359055”;
3、如果没有数字,则输出空字符串(“”)而不是NULL;

思路

遍历字符串,遇到数字时开启内层循环直到到达数字结尾,更新最长字符及其长度。

代码实现1

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

int main(){
    string str;
    while(cin>>str){
        int max_len = 0;
        string tmp_str;
        string output;
        for(int i = 0; i<str.size(); i++){
            if(str[i]>='0' && str[i]<='9'){
                tmp_str += str[i];
                while(str[i+1] >= '0' && str[i+1]<='9'){
                    i++;
                    tmp_str += str[i];
                }
                if(tmp_str.size() > max_len){
                    max_len = tmp_str.size();
                    output = tmp_str;
                }else if(tmp_str.size() == max_len)
                    output = tmp_str;
            }
            tmp_str.clear();
        }
        cout<<output<<","<<max_len<<endl;
    }
}

代码实现2

只保留字符串的首尾。

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

bool is_num(char x){
    if(x>='0' && x<='9')
        return true;
    else
        return false;
}

int main(){
    string s;
    cin>>s;

    int start = 0, end = 0;
    int best_start = 0, best_end = 0;
    while(start<s.size() && end<s.size()){
        while(start<s.size() && !is_num(s[start]))
            start++;
        if(start>=s.size())
            break;
        end = start;
        while(end<s.size() && is_num(s[end]))
            end++;
        if(end-start >= best_end-best_start){
            best_end = end;
            best_start = start;
        }
        start = end;
    }
    cout<<s.substr(best_start, best_end-best_start)<<","<<best_end-best_start<<endl;
}

题目二 字节流解析

根据数值占用BIT数,按顺序从输入字节流中解析出对应数值,解析顺序按输入数组astElement索引升序;
void Decode(unsigned int uiInputLen, unsigned char aInputByte[], unsigned int uiElementNum, ELEMENT_STRU astElement[]);
unsigned int uiInputLen:字节数组(流)长度
unsigned char aInputByte:字节数组(流)
unsigned int uiElementNum:解析数值个数
ELEMENT_STRU astElement[]:数值的结构数组指针,含义如下
Struct
{
unsigned int uiElementLength; //表示uiElementValue占用BIT数,范围1~32
unsigned int uiElementValue; //从字节流中按顺序解析的数值,用于输出
}ELEMENT_STRU;

输入描述:
字节数组长度uiIutputLen为3;
字节数组aInputByte[3]为{0x62, 0x80, 0x00},对应二进制为“0110 0010, 1000 0000, 0000 0000”;
解析数值个数uiElementNum为2;
数值[0]的值占4个bit,即astElement[0].uiElementLength = 4;
数值[1]的值占5个bit,即astElement[1].uiElementLength = 5;
输出描述:
数值[0]的值为6,二进制为“0110”,即astElement[0].uiElementValue = 6;
数值[1]的值为5,二进制为“0010 1”,即astElement[1].uiElementValue = 5;

示例1
输入
3
0x62 0x80 0x00
2
4
5
输出
6
5

思路

花了好大功夫才看懂这道题的意思。它的意思是,字节流中的各元素是以二进制01的形式连续排列的,指定bit的个数以从二进制字节流取出若干bit,然后转化为十进制输出。例如 0x62 0x80 实际上连在一起是 0110 0010 1000 0000,输入4,表示取4个bit得到0110,转化为十进制是6,接着输入5,表示接着取5个bit得到00101,转化为十进制是5。另外,这道题的难点主要在于进制准换以及相关的输入操作。

代码解答


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

int main() {
    int num; cin >> num;
    vector<long long> nums(num);
    for(int i=0; i < num; ++i) {
        cin >> hex >> nums[i];
    }

    int time; cin >> time;
    vector<int> times(time);
    for(int i=0; i < time; ++i) {
        cin >> dec >> times[i];
    }

    vector<bool> bits;
    for(int num: nums) {
        for(int i=0x80; i; i>>=1) {
            bits.push_back(num&i);
        }
    }

    int start = 0;
    long long result = 0;
    for(int time: times) {
        for(int i=0; i<time; ++i) {
            result = 2*result + bits[i+start];
        }
        cout << result << endl;

        result = 0;
        start += time;
    }

    return 0;
}

题目三 长整数相乘

输入描述:
输入两个长整数,以空格隔开
输出描述:
输出相乘后的结果

示例1
输入
-12341234
43214321
输出
-533318047612114

思路

这题主要考察大数运算,基本上做法都是转化成字符串,实现两个数的乘法(小学学过的那种),实现关键在于进位。此外,还要留意输入数字可能是负值,在字符串处理时要注意。

代码实现

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


int multiply(const string strMultiplierA, const string strMultiplierB, string &strRst)
{
    //测试是否有乘数为空  
    if(strMultiplierA.empty() || strMultiplierB.empty())
        return -1;

    string strA = strMultiplierA;
    string strB = strMultiplierB;
    int lenA = strA.length();
    int lenB = strB.length();
    int strRst_length = 0;
    int lenC = (lenA + 1)*(lenB + 1);
    vector<int> pC(lenC, 0); //逆序存放的结果  
    vector<int> pA(lenA, 0); //逆序存放的乘数A
    vector<int> pB(lenB, 0); //逆序存放的乘数B

    //把乘数逆序放到数组pA中,若chengshuA是12345,则pA是54321  
    for(int index = 0; index != strA.size(); index++)
        pA[lenA - 1 - index] = strA[index] - '0';

    for(int index = 0; index != strB.length(); index++)
        pB[lenB - 1 - index] = strB[index] - '0';

    //每个位循环相乘
    for (int iB = 0; iB < lenB; iB++){
        for (int iA = 0; iA < lenA; iA++){ //pA的每个位循环与pB[iB]相乘
            //pC[iA+iB]利用iB起到移位的作用,如iB是十位数,则在乘法计算中要向后移动移位。  
            int temp = pC[iA+iB] + pA[iA] * pB[iB];
            pC[iA+iB] = temp % 10;
            int carry = temp / 10; //进位  

            int x = iA + iB + 1;
            //lenC足够大;大数相加与数相乘同时计算,进位有可能是多位数  
            while (carry != 0){
                //进位不等于0
                pC[x] = pC[x] + carry % 10;//若前面有进位,则提前把进位加到求和结果p[x]上  
                carry = carry / 10;
                x++;
            }
        }
    }

    //判断结果有几位 
    while (lenC--){
        if (pC[lenC] != 0){
            strRst_length = lenC + 1;
            break;
        }
    }
    char ch;
    for (int i = strRst_length - 1; i >= 0; i--)  //把结果放入字符串中  
    {
        ch = pC[i] + '0';
        strRst.push_back(ch);
    }
    if (strRst.empty())//如果结果为0,则输出字符串为“0”  
        strRst = "0";

    return 0;
}

int main(void)
{
    string A ;
    string B ;
    cin>>A;
    cin>>B;
    int neg_count = 0;
    if(A[0]=='-'){
        A = A.substr(1,A.size()-1);
        neg_count++;
    }
    if(B[0]=='-'){
        B = B.substr(1,B.size()-1);
        neg_count++;
    }
    string strRst = "\0";
    multiply(A, B, strRst);
    if(neg_count==1) 
        cout<<"-"; 
    cout << strRst<<endl;

    return 0;
}

参考

【牛客网】[编程题]在字符串中找出连续最长的数字串
【博客】OJ 系列之字节流解析
【博客】两个任意长度的长整数相乘(华为oj,C++)

阅读更多

没有更多推荐了,返回首页