华为2012机试题目及解答(仅供参考,版权归华为所有)
问题1:
通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。
比如字符串“abacacde”过滤结果为“abcde”。
要求实现函数:
void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr);
【输入】 pInputStr: 输入字符串
lInputLen: 输入字符串长度
【输出】 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
【注意】只需要完成该函数功能算法,中间不需要有任何IO的输入输出
示例
输入:“deefd” 输出:“def”
输入:“afafafaf” 输出:“af”
输入:“pppppppp” 输出:“p”
//O(L1+26) 空间为O(1) void stringFilter1(const char *pInputStr,long lInputLen,char *pOutputStr) { if (pInputStr ==NULL || lInputLen <1) return; int letterCount=0; int abc[26]; memset(abc,-1,sizeof abc); int i; for( i=0;i<lInputLen;++i) { int index=pInputStr[i]-'a'; if (index <0 || index >= 26) //边界检测 continue; if ( abc[index] == -1 && letterCount<26) { abc[index] = letterCount; ++letterCount; } } //根据abc[]构造pOutputStr for(i=0;i<26;++i) { if (abc[i]!=-1) { pOutputStr[abc[i]]=(char)(0x61+i); } } pOutputStr[letterCount]='\0'; } //O(L1*L2) 空间为O(1) L1为输入字符串实际长度,L2为输出字符串实际长度 void stringFilter2(const char *pInputStr, long lInputLen, char *pOutputStr) { if (pInputStr ==NULL || lInputLen <1) return; int i,j,k; *pOutputStr=*pInputStr; k=1; //指到pOutputStr尾部的后一位 for (i=1;i<lInputLen;++i) { bool isExisting=false; for(j=0;j<k;++j) { if(pInputStr[i] == pOutputStr[j]) { isExisting=true; break; } } if (isExisting) { continue; } else { pOutputStr[k++]=pInputStr[i]; } } pOutputStr[k]='\0'; //记得在末尾加上NULL字符 }
问题2:
通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出现的重复字母进行压缩,并输出压缩后的字符串。
压缩规则:
1. 仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc".
2. 压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"
要求实现函数:
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr);
【输入】 pInputStr: 输入字符串
lInputLen: 输入字符串长度
【输出】 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
【注意】只需要完成该函数功能算法,中间不需要有任何IO的输入输出
示例
输入:“cccddecc” 输出:“3c2de2c”
输入:“adef” 输出:“adef”
输入:“pppppppp” 输出:“8p”
注意要考虑个数超出10的情况!
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr) { if(pInputStr ==NULL || lInputLen<1) return; int i,j,k=0; for(i=0;i<lInputLen;i=j){//遍历输入字符串 for(j=i+1;j<lInputLen;j++){//统计后续字符与当前字符重复的个数 if(pInputStr[j]!=pInputStr[i]){//一直到不与当前字符相等 break; } } if(j!=i+1){//字符重复次数不为1 int repeatCount=j-i; char numStr[10]; _itoa(repeatCount,numStr,10); strcat(pOutputStr,numStr); k=strlen(pOutputStr); } pOutputStr[k++]=pInputStr[i];//k为输出字符数组长度 pOutputStr[k]='\0'; } }
问题3:
通过键盘输入100以内正整数的加、减运算式,请编写一个程序输出运算结果字符串。
输入字符串的格式为:“操作数1 运算符 操作数2”,“操作数”与“运算符”之间以一个空格隔开。
补充说明:
1. 操作数为正整数,不需要考虑计算结果溢出的情况。
2. 若输入算式格式错误,输出结果为“0”。
要求实现函数:
void arithmetic(const char *pInputStr, long lInputLen, char *pOutputStr);
【输入】 pInputStr: 输入字符串
lInputLen: 输入字符串长度
【输出】 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
【注意】只需要完成该函数功能算法,中间不需要有任何IO的输入输出
示例
输入:“4 + 7” 输出:“11”
输入:“4 - 7” 输出:“-3”
输入:“9 ++ 7” 输出:“0” 注:格式错误
主要分为3步,提取-验证-计算,最后返回结果,这题要考虑的东西挺多的,转换可以用到itoa。问题3的异常情况较多,下次整理好代码再发。
void arithmetic(const char *pInputStr, long lInputLen, char *pOutputStr) { const char *input = pInputStr; char *output = pOutputStr; int sum = 0; int operator1 = 0; int operator2 = 0; char *temp = new char[10]; //保存运算符段信息 char *ope = temp; //获得操作数1 while(isNum(*input)) { sum = sum*10 + (*input++ - '0'); } operator1 = sum; sum = 0; //提取运算符段信息 while(!isNum(*input) && *input!='\0') { *temp++ = *input++; } *temp = '\0'; //处理格式错误的情况,必须为_+_或_-_这种形式 if (strcmp(ope," + ") != 0 && strcmp(ope," - ") !=0) { *output++ = '0'; *output = '\0'; delete[] ope; return; } else { ++ope; //指向运算符位置 } //获得操作数2 while(*input != '\0') { sum = sum*10 + (*input++ - '0'); } operator2 = sum; sum = 0; switch (*ope) { case '+':itoa(operator1+operator2,pOutputStr,10); break; case '-':itoa(operator1-operator2,pOutputStr,10); break; default: *output++ = '0'; *output = '\0'; delete[] ope; return; } }
//测试用例有: //12_+_25 //12_+25 //12+25 //12+_25 //12_++_25 //_+25 void main() { char *inputStr=new char[100]; char *outputStr=new char[100]; while(cin.getline(inputStr,100)) { memset(outputStr,0,sizeof outputStr); arithmetic(inputStr,strlen(inputStr),outputStr); //stringZip(inputStr,strlen(inputStr),outputStr); //stringFilter1(inputStr,strlen(inputStr),outputStr); cout<<outputStr<<"^"<<endl; } delete []inputStr; delete []outputStr; }