这个周末参加了一个阿里的笔试,一个华为的机试,上周参加了网易的笔试,阿里的笔试非常正式,答题卷 是那种要涂的,和四六级一样网易感觉很小气,题目多就算了,答题的空间都比较少,没地方写华为的机试,感觉最坑,题目简单,最好要对考试环境比较适应,那些电脑比较卡,我今天换了五台电脑,才登上华为的机试系统,此时别人已经做了几分钟,后面又要填信息,居然又报错,坑爹啊,写的学校名字一样的,居然也报错,等我把注册信息弄好,别人做了十几分钟了,我的那个急啊!提交答案的时候更坑爹啊,慢得要死,看bug更慢!所以去华工大学城机试的话,最好提前去,熟悉环境,找一台不卡,可以登上华为考试系统的机子。
还有一点要非常注意:我们平时写界面程序写习惯了,都不怎么习惯从控制台dos界面获得输入,这一点今天我也吸取了教训,第一题刚开始就想这个最基础的问题去了,悲剧,况且输入是不定长的,所以要自己判断输入的结束
第一题
#include<iostream>
using namespace std;
void main()
{
unsigned long int a[100],b[1001];
char c;
//这里用数组B记录每个数出现的次数,每出现一次就加1,初始化为1
int i;
for( i=0;i<1001;i++)
b[i]=1;
//获得输入
i = 0 ;
int count = 0;//记录数据的个数
//注意对错误输入的处理,这里很重要!!!
//当然也可以提交看错误的提示,对应修改
while(true)
{
//获得一个数字,如果输入一个换行符呢,cin遇到enter,认为此次输入结果,不读取enter,丢弃enter
cin>>a[i++];
if(cin.fail())//如果输入的不是int ,则cin.fail()返回true ,并阻塞在这里,直到清除错误标记,并且把这个字符读走
{
cout<<"输入有误!"<<endl;
cin.clear();
c=cin.get();
cin>>a[i-1];
}
//获得一个分隔符,比如逗号
c=cin.get(); //cin.get()可以读取换行符,enter
if(c=='\n')
break;
}
count = i;
//输出
for(i=0;i<count;i++)
{
cout<<(a[i]*b[a[i]]++); //每次相同的数据出现一次,则该数倍数加1
if(i<count-1)
cout<<",";
}
//system("pause");
}
/*
* 对一个32位无符号整型数的二进制位倒转
*如25的32位二进制为0000 0000 0000 0000 0000 0000 0001 1001
*倒转后 变为 1001 1000 0000 0000 0000 0000 0000 0000
*/
#include<iostream>
using namespace std;
void main()
{
//b用来保存转换后的数
unsigned long int a=25,b=0;
int i = 0 ;
//与低16位依次做与操作,依次左移一位
unsigned long j = 0x00000001;
//与高16位依次做与操作,依次右移一位
unsigned long k = 0x80000000;
for(i=0;i<32;i++)
{
if(a&k)
cout<<"1";
else
cout<<"0";
k=k>>1;
}
cout<<endl;
k = 0x80000000;
unsigned long tempH=0;
unsigned long tempL=0;
for(i=0;i<16;i++)
{
//低16位
tempL=0;
if(i!=0)
j=j<<1; //注意这里的1 不要写成i ,这里我犯了一个错误,考场上也没找出来
// cout<<"j="<<j<<endl;
if(a&j)
tempL=1;
// cout<<i<<" tempL="<<tempL<<endl;
b += tempL<<(32-i-1);
//高16位
tempH=0;
if(i!=0)
k=k>>1;
// cout<<"k="<<k<<endl;
if( (a&k)!=0 ) //注意这里 != 的优先级比 & 高,一定要对与操作打括号,我今天败在了这里
tempH=1;
// cout<<i<<" tempH="<<tempH<<endl;
b += (tempH<<i);
}
k = 0x80000000;
for(i=0;i<32;i++)
{
if(b&k)
cout<<"1";
else
cout<<"0";
k=k>>1;
}
cout<<endl;
system("pause");
}
当然还有其它的方法,比如位向量,连续除以2放在一个数组中等,今天犯二了啊!!!
/*
* 对一个32位无符号整型数的二进制位倒转
*如25的32位二进制为0000 0000 0000 0000 0000 0000 0001 1001
*倒转后 变为 1001 1000 0000 0000 0000 0000 0000 0000
*/
#include<iostream>
using namespace std;
void main()
{
//b用来保存转换后的数
unsigned long int a=25,b=0;
int i = 0 ;
int temp[32];
for(i=0;i<32;i++)
{//取余数,根据求一个数的二进制的算法
temp[i] = a%2 ;
a = a/2 ;
}
for(i=0;i<32;i++)
{
cout<<temp[i];
b = b*2 + temp[i];
//这里有个bug
//b = b<<1 + temp[i]; 如果 b<<1 不用括号包住,输出结果为 0
// 又是运算符优先级问题!! 移位运算符的优先级比较低,最好用括号包住!!!
}
cout<<endl;
cout<<b<<endl;
system("pause");
}
题目是不是很简单啊?!
第三题
/* *对" ^_^ "两边的字符串进行匹配 *如 abc^_^abcd,则匹配的字符串为abc,返回2,即左边字符c出现的位置,为匹配字符的最大长度减1 *又 字符'?'可以代表任意一个字母,字符'&'可以代表一个或多个字母 *如 abc?^_^abcd, 则匹配的字符串为abcd,返回3, 因为字符'?'可以代表'd' */ #include<iostream> #include<string> using namespace std; void matchOne(const string &str,int &count,int &i,int &j,int flag); //左边的字符串 string str_left = "" ; //右边的字符串 string str_right = "" ; /* * return 匹配的最大长度减1,若没有匹配的则返回-1 */ int matchStr() { string str; cout<<"请输入:"; cin>>str; //保存左边字符串的结束位置 int i_left=str.find("^_^"); //保存右边字符串的开始位置 int i_right= i_left + 3; //保存匹配的最大长度,若没有匹配的则返回-1 int count = -1 ; //确保左右字符串的长度都不为0 if(i_left==0||i_right>=str.length()) return -1; //取得左边的字符串 str_left = str.substr(0,i_left); //取得右边的字符串 str_right = str.substr(i_right); //输出左右两边的字符串,作测试用的 cout<<"左边的字符串:"<<str_left<<"右边的字符串:"<<str_right<<endl; //i记录左边字符串的当前正在匹配的位置,j记录右边字符串当前正在匹配的位置 int i=0,j=0; //从第一个字符开始匹配 while( i<str_left.length() && j<str_right.length() ) {//若相同,则比较下一个 if(str_left[i]==str_right[j]) { ++i; ++j; ++count; continue; } else if(str_left[i]=='&') { matchOne(str_right,count,i,j,1); } else if(str_right[j]=='&') { matchOne(str_left,count,j,i,0); } //'?'可以代表任意一个字母 else if(str_left[i]=='?'||str_right[j]=='?') { ++i; ++j; ++count; continue; } } return count; } /* *若出现'&',则调用此函数处理,由于此符号可以代表一个或多个字符,情况有点多,所以作为一个函数处理 *做此题可以先写测试用例,考虑了各种情况,再写程序,会想得比较全面 * param1 str ,当前匹配字符未出现'&'的字符串 * param2 count 保存匹配的最大长度, * param3 i 当前匹配字符未出现'&'所在的位置,指另一个字符中的位置 * param4 j 当前匹配字符出现'&'所在的位置,指str中的位置 * param5 flag 标志位,为0时表示传递过来的str为str_left,为1时表示传递过来的str为str_right */ void matchOne(const string &str,int &count,int &i,int &j,int flag) { int temp=j; while(j<str.length() && str.at(j)!='&') { ++j; ++count; } if(j==str.length()) return; else if(temp==j) return; else if(str.at(j)=='&') { if(flag==0) { matchOne(str_right,count,i,++j,1); } else { matchOne(str_left,count,j,++i,0); } } } void main() { cout<<"匹配的长度为:"<<matchStr()<<endl; getchar(); system("pause"); }
华为机试注意事项(软件党)
今年华为机试用的是OJ平台,可选择的语言是C/C++,Java。由于本猿用的是C++,现在就机试期间可能遇到的问题给大家提供点机试意见,把这篇文章送给即将找工作的战友们!!!
1.注意工程的建立要建立Empty project。在这点很多人的习惯是建立一个包含"stdafx.h"的简单工程,而OJ平台只能接受一个文件,而包含预编译的工程至少包含两个文件,所以很多人提交代码以后,会发现自己的代码无法编译通过。
2.注意输入/输出。作为一个没有参加过编程比赛的人,机试过程中有很多时间浪费在这个上面。请记住以下一点:给你测试的是一个机器人。不要画蛇添足的写如:cout << "Please enter two numbers: " <<endl;这样的提示代码,一定要按照最简洁的输入/输出去写代码,因为对面的电脑并不知道你要做什么,从而把你判错。。。我在这里吃了大亏。。。
3.注意程序对异常的处理。注意答题要求,以及其对异常状态的提醒,并处理这些可能的异常。在这点上,我发现我有的同学代码写的没什么问题,但是无法得到满分,基本上华为给的状态提醒就是异常问题,所以,请注意异常。
4.错误查找的问题。当你提交完代码,过个几分钟,就可使在平台上查询自己的代码对错。对了当然是皆大欢喜,错了呢???作为一个机试小白,当时本猿可是两眼一抓瞎,在那里逮着代码一通瞎改。。。但是,现在我要告诉你!!错了请查找OJ平台左上方的状态栏,在这里你可以看到自己的错误到底是因为什么,具体的嘛,到时候你自然就知道啦。
最后,加上一点,考场上遇到麻烦怎么办???请找监考,请不要一个人在哪里瞎折腾,时间就是金钱(这句话至少在你找工作的时候是真的!),而且,考场的监考还是蛮热心的,哈哈~~~