下面是华为的上机编程考试题目,想加入华为的可以看看,不想加入的也可以来找一找C语言编程的感觉,毕竟各大IT公司对程序员的基本素质考察都差不多,下面的题目的实现代码是我自己编写的,其中有很详细的注释,并且每个程序都已经在Visual C++ 6.0上运行通过了。程序中包含的不足之处还请谅解,欢迎大家到我的CSDN技术博客和我交流探讨。
2010年华为软件校园招聘编程测验
类别:软件C语言
编程题(共2题,第一题40分,第二题60分,共100分。请上机编写程序,按题目要求提交文件。[详见考试说明]
本试题采用自动测试用例进行评分,测试用例不对考生公开,凡不满足提交要求导致不能运行或用例不通过,不予评分)。
1. 删除字符串中所有给定的子串(40分)
问题描述:
在给定字符串中查找所有特定子串并删除,如果没有找到相应子串,则不作任何操作。
要求实现函数:
int delete_sub_str(const char *str, const char *sub_str, char *result_str)
【输入】 str:输入的被操作字符串
sub_str:需要查找并删除的特定子字符串
【输出】 result_str:在str字符串中删除所有sub_str子字符串后的结果
【返回】 删除的子字符串的个数
注:
I、 子串匹配只考虑最左匹配情况,即只需要从左到右进行字串匹配的情况。比如:
在字符串"abababab"中,采用最左匹配子串"aba",可以匹配2个"aba"字串。如果
匹配出从左到右位置2开始的"aba",则不是最左匹配,且只能匹配出1个"aba"字串。
II、 输入字符串不会超过100 Bytes,请不用考虑超长字符串的情况。
示例
输入:str = "abcde123abcd123"
sub_str = "123"
输出:result_str = "abcdeabcd"
返回:2
输入:str = "abcde123abcd123"
sub_str = "1234"
输出:result_str = "abcde123abcd123"
返回:0
程序代码(C语言):
/*删除字串函数,在src中删除sub子串,并将结果保存在result字符串中*/
int delSubStr(char * src,char * sub,char * result)
{
char * src_p=src;
char * sub_p=sub;
char * res_p=result;
int count=0;//记录包含子串的个数
int sub_len=strlen(sub);//记录子串的长度
char * temp;//临时保存子串的副本
temp=(char *)malloc(sub_len+1);
memset(temp,'/0',sub_len+1);
while(*src_p)
{
memcpy(temp,src_p,sub_len);
/*原串中包含与sub完全匹配的子串*/
if(!strcmp(temp,sub))
{
count++;
src_p+=sub_len;
}
else
*res_p++=*src_p++;
*res_p='/0';
free(temp);
return count;//返回包含子串的个数
}
void main()
{
char result[100];
int count=delSubStr("abcdefgde","de",result);
printf("The new string is:");
printf("%s/n",result);
printf("count is:");
printf("%d/n",count);
}
2. 高精度整数加法(60分)
问题描述:
在计算机中,由于处理器位宽限制,只能处理有限精度的十进制整数加减法,比如在32位宽处理器计算机中,
参与运算的操作数和结果必须在-231~231-1之间。如果需要进行更大范围的十进制整数加法,需要使用特殊
的方式实现,比如使用字符串保存操作数和结果,采取逐位运算的方式。如下:
9876543210 + 1234567890 = ?
让字符串 num1="9876543210",字符串 num2="1234567890",结果保存在字符串 result = "11111111100"。
-9876543210 + (-1234567890) = ?
让字符串 num1="-9876543210",字符串 num2="-1234567890",结果保存在字符串 result = "-11111111100"。
要求编程实现上述高精度的十进制加法。
要求实现函数:
void add (const char *num1, const char *num2, char *result)
【输入】num1:字符串形式操作数1,如果操作数为负,则num1[0]为符号位'-'
num2:字符串形式操作数2,如果操作数为负,则num2[0]为符号位'-'
【输出】result:保存加法计算结果字符串,如果结果为负,则result[0]为符号位。
注:
I、 当输入为正数时,'+'不会出现在输入字符串中;当输入为负数时,'-'会出现在输入字符串中,且一定在输入字符串最左边位置;
II、 输入字符串所有位均代表有效数字,即不存在由'0'开始的输入字符串,比如"0012", "-0012"不会出现;
III、 要求输出字符串所有位均为有效数字,结果为正或0时'+'不出现在输出字符串,结果为负时输出字符串最左边位置为'-'。
示例
输入:num1 = "580"
num2 = "-50"
输出:result = "530"
输入:num1 = "580"
num2 = "-600"
输出:result = "-20"
程序代码(C语言):
/*判断字符串整数是否合法,合法返回'1',否则返回'0'*/
int isLegalNum(const char * num)
{
const char * num_p=num;
int num_len;//记录整数长度(不包含符号位和结束符'/0')
/*字符串指针为空,不是合法的整数,返回'0'*/
if(num_p==NULL)
return 0;
if(*num_p=='-')
num_p++;
num_len=strlen(num);
/*不合法整数,返回'0'*/
if(*num_p<=48||*num_p>57)
return 0;
int i;
for(i=0;i<num_len;i++)
{
/*不合法整数,返回'0'*/
if(*num_p>57||*num_p<48)
return 0;
}
return 1;
}
/*将字符串逆序*/
void reverseStr(char * result)
{
int i;
char temp;
int res_len=strlen(result);
for(i=0;i<res_len/2;i++)
{
temp=result[i];
result[i]=result[res_len-i-1];
result[res_len-i-1]=temp;
}
}
/*加法函数,用于将两个字符串形式的整数相加,结果保存在 char * result 中*/
void add (const char * num1, const char * num2, char * result)
{
/*判断两个字符串整数 num1 和 num2 是否合法,如果不合法则要求用户重新输入*/
if(!(isLegalNum(num1)&&isLegalNum(num2)))
{
strcpy(result,"对不起,您输入的字符串整数不是合法的十进制整数,请您检查后重新输入,谢谢合作!");
return;
}
int count=0;//记录进位或借位
const char * num1_p;//记录第一个数的字符串起始地址
const char * num2_p;//记录第二个数的字符串起始地址
char * res_p=result;//记录结果字符串起始地址
int num1_len=strlen(num1);//第一个数的长度
int num2_len=strlen(num2);//第二个数的长度
num1_p=num1+num1_len-1;//num1_p指向第一个数的最后一位
num2_p=num2+num2_len-1;//num2_p指向第二个数的最后一位
/*加法运算,此时两个数的符号相同*/
if((*num1!='-'&&*num2!='-')||(*num1=='-'&&*num2=='-'))
{
/*两个负数相加*/
if(*num1=='-'&&*num2=='-')
{
num1_len--;
num2_len--;
int i;
for(i=0;i<(num2_len>num1_len?num1_len:num2_len);i++)
{
*res_p++=(*num1_p-'0'+*num2_p-'0'+count)%10+'0';
count=(*num1_p-'0'+*num2_p-'0'+count)/10;
num1_p--;
num2_p--;
}
/*如果第一个数的长度大于第二个数*/
if(num1_len>num2_len)
{
for(i=0;i<num1_len-num2_len;i++)
{
*res_p++=(*num1_p-'0'+count)%10+'0';
count=(*num1_p-'0'+count)/10;
num1_p--;
}
}
/*如果第一个数的长度小于第二个数*/
else if(num1_len<num2_len)
{
for(i=0;i<num2_len-num1_len;i++)
{
*res_p++=(*num2_p-'0'+count)%10+'0';
count=(*num2_p-'0'+count)/10;
num2_p--;
}
}
/*向最高位进一位*/
if(count==1)
*res_p++='1';
*res_p++='-';
*res_p='/0';
reverseStr(result);
}
/*两个正数相加*/
if(*num1!='-'&&*num2!='-')
{
int i;
for(i=0;i<(num2_len>num1_len?num1_len:num2_len);i++)
{
*res_p++=(*num1_p-'0'+*num2_p-'0'+count)%10+'0';
count=(*num1_p-'0'+*num2_p-'0'+count)/10;
num1_p--;
num2_p--;
}
/*如果第一个数的长度大于第二个数*/
if(num1_len>num2_len)
{
for(i=0;i<num1_len-num2_len;i++)
{
*res_p++=(*num1_p-'0'+count)%10+'0';
count=(*num1_p-'0'+count)/10;
num1_p--;
}
}
/*如果第一个数的长度小于第二个数*/
else if(num1_len<num2_len)
{
for(i=0;i<num2_len-num1_len;i++)
{
*res_p++=(*num2_p-'0'+count)%10+'0';
count=(*num2_p-'0'+count)/10;
num2_p--;
}
}
/*向最高位进一位*/
if(count==1)
*res_p++='1';
*res_p='/0';
reverseStr(result);
}
}
/*减法运算,此时两个数的符号不同*/
else
{
int temp=1;//记录num1和num2哪一个是负数,默认认为num1为负数
/*num1为负数*/
if(*num1=='-')
{
num1++;
num1_len--;
}
/*num2为负数*/
else
{
temp=2;
num2++;
num2_len--;
}
/*num1绝对值大*/
if(num1_len>num2_len||num1_len==num2_len&&strcmp(num1,num2)>0)
{
int i;
for(i=0;i<num2_len;i++)
{
/*不借位*/
if(*num1_p-count>=*num2_p)
{
*res_p++=(*num1_p-*num2_p-count)%10+'0';
count=0;
}
/*借位*/
else if(*num1_p-count<*num2_p)
{
*res_p++=(*num1_p+10-*num2_p-count)%10+'0';
count=1;
}
num1_p--;
num2_p--;
}
for(i=0;i<num1_len-num2_len;i++)
{
/*不借位*/
if(*num1_p-'0'-count>=0)
{
*res_p++=(*num1_p-'0'-count)%10+'0';
count=0;
}
/*借位*/
else if(*num1_p-'0'-count<0)
{
*res_p++=(*num1_p+10-'0'-count)%10+'0';
count=1;
}
num1_p--;
}
do
{
res_p--;
}
while(*res_p=='0');
/*num1是负数且绝对值大,所以此时结果为负数*/
if(temp==1)
{
res_p++;
*res_p++='-';
*res_p='/0';
reverseStr(result);
}
/*num1是正数且绝对值大,所以此时结果为正数*/
else if(temp==2)
{
res_p++;
*res_p='/0';
reverseStr(result);
}
}
/*num2绝对值大*/
else if(num1_len<num2_len||num1_len==num2_len&&strcmp(num1,num2)<0)
{
int i;
for(i=0;i<num1_len;i++)
{
/*不借位*/
if(*num2_p-count>=*num1_p)
{
*res_p++=(*num2_p-*num1_p-count)%10+'0';
count=0;
}
/*借位*/
else if(*num2_p-count<*num1_p)
{
*res_p++=(*num2_p+10-*num1_p-count)%10+'0';
count=1;
}
num1_p--;
num2_p--;
}
for(i=0;i<num2_len-num1_len;i++)
{
/*不借位*/
if(*num2_p-'0'-count>=0)
{
*res_p++=(*num2_p-'0'-count)%10+'0';
count=0;
}
/*借位*/
else if(*num2_p-'0'-count<0)
{
*res_p++=(*num2_p+10-'0'-count)%10+'0';
count=1;
}
num2_p--;
}
do
{
res_p--;
}
while(*res_p=='0');
/*num1是负数且绝对值小,所以此时结果为正数*/
if(temp==1)
{
res_p++;
*res_p='/0';
reverseStr(result);
}
/*num1是正数且绝对值小,所以此时结果为负数*/
else if(temp==2)
{
res_p++;
*res_p++='-';
*res_p='/0';
reverseStr(result);
}
}
/*num1和num2绝对值相等且异号,所以结果为'0'*/
else
{
*res_p++='0';
*res_p='/0';
}
}
}
void main()
{
char result[100];//保存结果的字符串
char num1[100];
char num2[100];
printf("请输入两个整数(整数之间用空格作为间隔符):");
scanf("%s %s",num1,num2);
add(num1,num2,result);
printf("The result is:");
printf("%s/n",result);
}
转载自原文链接, 如需删除请联系管理员。
原文链接:分享两道华为的C语言上机题——包含答案。,转载请注明来源!