华为2014年四道笔试算法题

本文分享了四道疑似华为笔试的算法题,涉及字符串过滤、压缩、100以内正整数的加减运算,以及求数字序列中最小数和最大数之和。题目要求实现特定功能的函数,不包含IO操作。
摘要由CSDN通过智能技术生成

1.说明

这四道笔试题是在网上看到的,不确定是否真的是华为的笔试题,只是出于兴趣,草草的做了一下,顺便将代码记于此。

2.第一题

通过键盘输入一串小写字母(a~z)组成的字符串。

请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。

比如字符串“abacacde”过滤结果为“abcde”。

要求实现函数:void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr);

【输入】 pInputStr: 输入字符串
lInputLen: 输入字符串长度
【输出】 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;

【注意】只需要完成该函数功能算法,中间不需要有任何IO的输入输出

示例

输入:“deefd” 输出:“def”
输入:“afafafaf” 输出:“af”
输入:“pppppppp” 输出:“p”

main函数已经隐藏,这里保留给用户的测试入口,在这里测试你的实现函数,可以调用printf打印输出
当前你可以使用其他方法测试,只要保证最终程序能正确执行即可,该函数实现可以任意修改,但是不要改变函数原型。

void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr)
{
    if(!pInputStr || !pOutputStr)
        return;
    bool flag[26] = {false};
    const char *pCur = pInputStr;
    int iIndex = 0, iPos = 0;
    while(*pCur != '\0') {
        iIndex = *pCur - 'a';
        if(!flag[iIndex]) {
            flag[iIndex] = true;
            pOutputStr[iPos++] = *pCur;
        }
        ++pCur;
    }
    pOutputStr[iPos] = '\0';
}

int main() {
    char input[] = "ppppppppp";
    char *output = new char [strlen(input) + 1];
    stringFilter(input, strlen(input), output);
    std::cout << output << std::endl;
    delete []output;
    return 0;
}

3.第二题

通过键盘输入一串小写字母(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”

 void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr) {
    if(!pInputStr || !pOutputStr)
        return;
    int iNum = 1;
    char Number[10] = {0}; //'9''9''9''9''9''9''9''9''9''\0'
    const char *pCur = pInputStr + 1;
    int iPos = 0;

    while(*pCur != '\0') {
        while(*pCur != '\0' && *pCur == *(pCur - 1)) {
            ++iNum;
            ++pCur;
        }
        //流程跳转到这里,表示连续字符终止
        if(iNum > 1) {
            memset(Number, 0, sizeof(Number));
            sprintf(Number, "%d", iNum);
            sprintf(pOutputStr + iPos, "%s%c", Number, *(pCur - 1));
            iPos += strlen(Number) + 1;
            iNum = 1;
        } else {
            sprintf(pOutputStr + iPos, "%c", *(pCur - 1));
            ++iPos;
        }
        ++pCur;
    }
    if(iNum == 1) {
        sprintf(pOutputStr + iPos, "%c", *(pCur - 1));
        ++iPos;
    }
    pOutputStr[iPos] = '\0';
 }

int main() {
    char input[] = "adef";
    char *output = new char [strlen(input) + 1];
    stringZip(input, strlen(input), output);
    std::cout << output << std::endl;
    delete []output;
    return 0;
}

4.第三题

通过键盘输入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” 注:格式错误

void arithmetic(const char *pInputStr, long lInputLen, char *pOutputStr) {
   if(!pInputStr || !pOutputStr)
       return ;
    const char *pCur = pInputStr;
    char *pTemp = new char[4];  //一百以内的正整数不会超过3位,外加一个结束符
    uint uNumA = 0, uNumB = 0;
    int uResult = 0;
    char cOpt;
    while(*pCur != ' ') ++pCur;
    //拷贝第一个操作数字符
    memset(pTemp, 0, 4);
    memcpy(pTemp, pInputStr, pCur - pInputStr);
    sscanf(pTemp, "%d", &uNumA);
    ++pCur;  //跳过空格
    cOpt = *pCur++;
    if(*pCur == ' ') {
        ++pCur;
        const char *pSecond = pCur; //记录第二个操作数的起点
        while(*pCur != '\0') ++pCur;
        //拷贝第二个操作数字符
        memset(pTemp, 0, 4);
        memcpy(pTemp, pSecond, pCur - pSecond);
        sscanf(pTemp, "%d", &uNumB);

        //开始计算结果
        switch (cOpt) {
            case '+':
                uResult = uNumA + uNumB;
                break;
            case '-':
                uResult = uNumA - uNumB;
                break;
            default:
                uResult = 0;    //未知的操作符也视为错误
        }
    }

    //输出结果
    sprintf(pOutputStr, "%d", uResult);
    delete []pTemp;
}

int main() {
    char input[] = "5 -- 10";
    char output[4] = {0};
    arithmetic(input, strlen(input), output);
    cout << output << endl;
    return 0;
}

5.第四题

输入1–50个数字,求出最小数和最大数的和。假设数值用’,’号分割。

void swap(int *input, int i, int j) {
    int temp = input[i];
    input[i] = input[j];
    input[j] = temp;
}

int partition(int *input, int low, int high) {
    int base = input[low];
    while(low < high) {
        while(low < high && input[high] >= base) {
            --high;
        }
        swap(input, low, high);
        while(low < high && input[low] <= base) {
            ++low;
        }
        swap(input, low, high);
    }
    return low;
}

void QSort(int *input, int low, int high) {
    if(low < high) {
        int lastlow = partition(input, low, high);
        QSort(input, low, lastlow -1);
        QSort(input, lastlow + 1, high);
    }
}

void QuickSort(int *input, int ilen) {
    if(!input)
        return;
    QSort(input, 0, ilen - 1);
}
int main() {
    //接收输入
    string input;
    int Array[N] = {0};
    cout << "Please enter some numbers:";
    cin >> input;

    //分割字符串为单个数字
    const char *pCur = input.c_str();
    const char *pStart = input.c_str();
    char cTemp[10] = {0};
    int iFactor = 1;  //系数 可为1或者-1
    int iValue = 0, iIndex = 0;
    while(*pCur != '\0') {
        //首先判断输入的数字是否显式的带有符号,比如:+10,-20
        if(*pCur == '+') {
            iFactor = 1;
            ++pCur; //对于'+'直接跳过即可
        } else if(*pCur == '-') {
            iFactor = -1;
            ++pCur;
        } else {
            iFactor = 1;
        }

        //记录数字字符的开始位置
        pStart = pCur;
        while(*pCur != ',' && *pCur != '\0') ++pCur;

        //拷贝数字字符到临时数组
        memset(cTemp, 0, 10);
        memcpy(cTemp, pStart, pCur - pStart);

        //转换为数值,并添加到数组
        sscanf(cTemp, "%d", &iValue);
        Array[iIndex++] = iValue * iFactor;

        //跳过','
        if(*pCur == ',')
            ++pCur;
    }

    //快速排序
    QuickSort(Array, iIndex);

    //计算最小和最大值之和
    cout << "Sum = " << Array[0] + Array[iIndex - 1] << endl;

    //打印数组
    /*
    for(int i = 0; i < iIndex; ++i) {
         cout << Array[i] << endl;
    }
     */
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值