华为笔试题
华为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[]:数值的结构数组指针,含义如下
{
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++)
相关阅读
华为手机照片删除了怎么恢复??很多时候我们相册中的图片是在清理手机时,不小心删掉的,可是后来想去查看的时候往往找不到了,可真是后悔
2019年BrandZ中国出海品牌50强出炉:华为果然是第一
A5创业网(公众号:iadmin5)3月30日消息:WPP与凯度今日在北京发布《2019年BrandZ中国出海品牌50强报告》。今年中国品牌的品牌力指数同
华为麒麟810如何?据悉6月21日,华为终端手机产品线总裁何刚在nova 5系列发布会上公布全新麒麟芯片:麒麟810。该处理器是基于基于7nm
笔者以小米的品牌策略为例,向我们讲述了:进入新消费时代后,我们需要不断更新品牌思维,在产品里加入消费主义要素。大约在2013年的时候
问题一用户的出行计划里,⼤部分有交通工具(机票/⽕车)和酒店的预定诉求。但是,⽬前很多⽤户都是机票和酒店分开预定。请设计⼀款产