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