华为上机试题及面试

上机时,声明要写工业级代码,要考虑临界(edge case)条件等云云。。。

一、/* 题目描述:编写一个函数,统计出具有n个元素的一维数组中大于等于所有元素平均值的元素的个数并返回*/

问题一、考虑到数组的平均值可能不是int,即所有元素的和未必能被元素个数整除的情形,而float直接比较大小,是不精确的,与精度有关。

问题二、所有数组元素的和,会不会超出int的范围。而其编译环境却不支持long long 类型。

代码实现如下:

/* 题目描述:编写一个函数,统计出具有n个元素的一维数组中大于等于所有元素平均值的元素的个数并返回*/

/* 说明:请在这里实现下列函数, c/c++语法不限, 最后需要保证程序编译连接通过, 并生成test.exe文件. */
/* 相关宏定义及函数声明见'func.h'头文件 */

#include "func.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <iostream>

/* 请按照要求实现下列函数 */

int GetByondAvgNumber(int iArray[], int iLen)
{
   int i;

   long  sum = 0;
   for(i = 0; i < iLen; ++i) {
		sum += iArray[i];
   } 

   int avg = sum / iLen;
   if(sum > 0  && sum % iLen) {
       ++avg;
   }

  

   int count = 0;
   for(i = 0; i < iLen; ++i) {
	   if(iArray[i] >= avg) {
			++count;
	   }
   }

   return count;
}


/* mian函数已经隐藏,这里保留给用户的测试入口,在这里测试你的实现函数,可以调用printf打印输出*/
/* 当前你可以使用其他方法测试,只要保证最终程序能正确执行即可 */
/* 该函数实现可以任意修改,但是不要改变函数原型。一定要保证编译运行不受影响*/
void main_i()
{
    /* TODO: 请测试时改变改用例 */   
   //  int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -10};
	int a[] = {-2, -3, -2};
    /* TODO: 调用被测函数 */
	int count = GetByondAvgNumber(a, sizeof(a)/sizeof(a[0]));
	
	//std::cout << sizeof(long) << std::endl;

    /* TODO: 执行完成后可比较是否是你认为正确的值 */
	printf("count = %d \n", count);
	assert(count == 2);
    
}

二、

题目描述: 
数字可以在十进制和二进制之间进行转换。输入一个10进制数字,请编写一个函数,计算该数字对应二进制中0的个数,注意左数第一个1之前的所有0都不需要计算。

可以通过获取该数中二进制中一位,进行统计 1 右边0的个数;

问题一:移位的问题,有符号数的右移是有符号扩展的如-1,右移多少位后仍是-1,;

      解决方法1: 将该数转化为无符号数;

     解决方法2:统计该数的32位每一位,仅一次;

/*
题目描述: 
数字可以在十进制和二进制之间进行转换。输入一个10进制数字,请编写一个函数,计算该数字对应二进制中0的个数,注意左数第一个1之前的所有0都不需要计算。
*/
/* 请在这里实现下列函数, c/c++语法不限, 最后需要保证程序编译连接通过, 并生成test.exe文件. */
/* 相关宏定义及函数声明见'func.h'头文件 */

#include "func.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>



/* 请按照要求实现下列函数 */
#define NULL_PTR   0L

/*
void GetZeroNum(const int *pIn, int *pOut)
{
	//防止指针为空
	assert(pIn != NULL_PTR && pOut != NULL_PTR);

	int i;

	int n = *pIn;
	int count = 0;
	int bits = sizeof(int) << 3;
    
	for( i = 0; i < bits; ++i) {
		if(!n) break;  // n为0 时,

		if(!(n&1)) { //取n的最低位
			++count;
		}

		n >>= 1;	
	}

	*pOut = count;

}
*/

void GetZeroNum(const int *pIn, int *pOut)
{
	//防止指针为空
	assert(pIn != NULL_PTR && pOut != NULL_PTR);

	unsigned int n = (unsigned int) *pIn;
	int count = 0;

    
	while(n) {
		if(!(n&1)) { //取n的最低位, 若为0
			++count;
		}

		n >>= 1;	
	}

	*pOut = count;

}





/* main函数已经隐藏,这里保留给用户的测试入口,在这里测试你的实现函数,可以调用printf打印输出*/
/* 当前你可以使用其他方法测试,只要保证最终程序能正确执行即可 */
/* 该函数实现可以任意修改,但是不要改变函数原型。一定要保证编译运行不受影响*/
void TestEntry()
{
    /* TODO: 请测试时改变改用例 */
    int  testNums[] = { -32, -7, -1, 0, 32, 1024, 2048, 0x80000000};
	int  zeroNums[] = {5,     2,  0, 0,  5,   10,   11,      31};
	
	int testNum = 32;	 
	int  zeroNum = 0;
	
	/*
	int n = -1; 
	printf("n >> 1 = %d\n", n >> 1);  // print n >> 1 = -1 ;带符号扩展
    printf("n >> 1 = %0x\n", n >> 1);  // print n >> 1 =  0xffff ffff 带符号扩展
	
	unsigned int m = (unsigned) n;
	printf("m >> 1 = %d \n", m >> 1);  //无符号扩展
    printf("m >> 1 = %0x\n", m >> 1);  //无符号扩展  print m >> 1 = 0x7fff ffff
    */

    /* TODO: 调用被测函数 */
	int i;
	int len = sizeof(testNums) / sizeof(testNums[0]);
	for(i = 0; i < len; ++i) { 	
		GetZeroNum(&testNums[i], &zeroNum);
		assert(zeroNum ==  zeroNums[i]);
    }

	GetZeroNum(&testNum, &zeroNum);
    /* TODO: 执行完成后可比较是否是你认为正确的值 */
    printf("\nzero num of %d is %d.\n", testNum, zeroNum);
	assert(zeroNum == 5);
}


三、求n个串的最长公共子串。

      最笨的方法:1.对于每个串求出其所有子串;

                            2.然后的对其子串出现的频度进行计数;同一个串的相同子串出现的次数只计一次;

                            3. 统计完所有子串后,出现频度为n的子串为n个串的公共子串,在所有公共子串中找到最长的那个公共子串。

    改进方法,1.两个串的所有子串求交集,生成初始的公共子串集;

                       2. 对于剩余的n-2串中串i, 将串i的子串集与公共子串集求交集,作为新的公共子串集;

                       3. 最后的公共子串集,就是n个串的所有公共子串,在其中找出长度最长的子串。


方法一的实现:如下:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>


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


//将字符串str的所有子串放在vector v中
void getSubStrings(const char *str, vector<string> &v) {
	assert(str != NULL);

	const int len = strlen(str) + 1;
    char tmp[200]; 	
	
	for(int i = 0; i < len; ++i){
		for(int j = i; j < len; ++j) {
            int subLen = j - i + 1; 
			strncpy(tmp, str + i, subLen);
			tmp[subLen] = '\0';
			string s(tmp);			

			v.push_back(s);
		}		
	}	
}




/* 请按照要求实现下列函数 */
//获取pIn中的n个子串中的所有子串
char* findSameSubStr(const char *pIn[], int n)
{
	
	int i;
	const int len = n;
	
	//获取所有串的子串
	vector<vector<string>>  vs;
	vs.resize(len);	
	for(i = 0; i < len; ++i) {	 
		getSubStrings(pIn[i], vs[i]);
    }

	
	map<string, int> counter;
	for(i = 0; i < len; ++i) {
		vector<string> v = vs[i]; //第i个string的所有子串
		vector<string> :: const_iterator it;        
		for(it = v.begin(); it != v.end(); ++it) {
			if(counter[*it] == i) { //使同一个字符串中相同子串的个数只统计一次 
				++counter[*it];
			}
		}		
	}
	
	


	int maxLen = 0;
	string maxStr;	
	map<string, int >::const_iterator it;
	for(it = counter.begin(); it != counter.end(); ++it) {
		if(it->second == n) {
			//初始化公共子串
			if(maxLen == 0) {
				maxStr = it->first;
				maxLen = maxStr.length();
			} 

			//获取最长的公共子串
			if((it->first).length() > maxLen) {
				maxStr = it->first;
				maxLen = maxStr.length();
			}

		}
	}

     char *commStr = (char *) malloc(maxLen + 1);
	 strncpy(commStr, maxStr.c_str(), maxLen);
	 commStr[maxLen] = '\0' ;
	 


    return commStr;
}


/* mian函数已经隐藏,这里保留给用户的测试入口,在这里测试你的实现函数,可以调用printf打印输出*/
/* 当前你可以使用其他方法测试,只要保证最终程序能正确执行即可 */
/* 该函数实现可以任意修改,但是不要改变函数原型。一定要保证编译运行不受影响*/
int  main(int argc, char *argv[]) {
    /* TODO: 请测试时改变改用例 */
   const char *strs[] = {
					"what is local bus how are you how are you how are you?",
					"Name some local bus.",
					"local bus is high speed I/O bus close to the processor.",
					};

    /* TODO: 调用被测函数 */

	char* commstr = findSameSubStr(strs, sizeof(strs) / sizeof(strs[0]));


    /* TODO: 执行完成后可比较是否是你认为正确的值 */

	if(commstr){
		printf("%s\n", commstr);
		free(commstr);
	}
	

	system("pause");


    
}


面试题:

看看简历,以及笔试题,自我介绍。

问你学过数据结构里的栈吧,实现一个栈?说着,给了三个接口, isEmpty(),  push(), pop(),让我在纸上写。。

答: 实现一个长度固定的栈,还是动态增长的栈, 他思索了一个说,就写个只有5个元素的栈。

#define MAX  5

typedef int item_t;

typedef struct stack{
	item_t a[MAX];
	int top; //top始终指向栈顶元素
} stack;

void init_stack(stack *s){
	assert(s != NULL);
	s->top = -1; //栈为空
}

int isEmpty(stack *s) {
	assert(s != NULL);
	
	return s->top == -1;
}

int isFull(statck *s) {
	assert(s !== NULL);

	return s->top == (MAX - 1);
}

void push(stack *s, item_t item) {
	assert(s != NULL);

	if(!isFull(s)) {
		s->a[++top] = item;
	}	
}

item_t pop(stack *s) {
	assert(s != NULL);

	if(!isEmpty(s)) {
		return s->a[top--];
	}
}


写完以后,我又认真誊写了一遍,给他看,看完后,说你可以去等着二面了。


二面是心理测试。 十几分钟搞定。

三面是谈人生,谈理想。。。

总之,感觉很水。。。。













  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值