1. 程式人生 > >華為2018春招筆試題

華為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;
}

參考