华为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;
}
posted @ 2013-10-14 19:05  Linka  阅读(460)  评论(0编辑  收藏  举报