替换字符串——华为笔试时的一道题

4 篇文章 0 订阅
1 篇文章 0 订阅

        昨天(2012-9-16)去学校二基楼参加华为的上机笔试,第三题是个替换字符串的,这题当场没做出来

(只做出2题、总共三题、两小时,我写代码的速度还是有些慢啊)。回来想了想还是挺好玩的又做了一

次,代码贴出来。

 

       题目大意:

       实现voidReplace(char *src, char *substr, char *replace, char *output); 

       1.src是源字符串,机器输入。

       2.substr是需要在src中查找的字符串,机器输入。有"?"代表任一个字符,"*"代表0个或多个任意

字符(查找最长匹配的字串,当时就是题目没要求、查成最短的了。之后发现样例里是按照最长匹配的...

改时费时过长最终没完成。什么是最长呢,就是acdcde被a*cd替换成xxe,而不是xxcde)。

       3.replace是需要替换的字符串,机器输入。

       4.output是用来输出的字符串。

       样例:

       Input: src = "abcdcde"; substr ="b?d";replace = "xxx";

       Output: "axxxcde"

       Input:src = "abcdcde"; substr ="b*cd";replace = "xxx";

       Output: "axxxe"

 

#include <iostream>
#include <sstream>

using namespace std;

// 自己定义的字符串拷贝,指定头、尾
void StrCpy(char *dst, char *src, int head, int tail)
{
    for (int i = head; i <= tail; ++i, ++dst)
    {
        *dst = src[i];
    }
    *dst = 0;
}

// 字符串倒置
void Reverse(char *src, int head, int tail)
{
    if (head >= tail)
    {
        return;
    }
    char c = src[head];
    src[head] = src[tail];
    src[tail] = c;

    Reverse(src, head + 1, tail - 1);
}

// 查找子串辅助性函数,返回头尾(head、tail)
bool FindSubstr(char *src, char *substr, int &head, int &tail)
{
    int i = 0, j = 0;
    for (i = 0; src[i] != 0; ++i)
    {
        if (src[i] == substr[j])
        {
            head = i;   // 查到子串,起点赋值给head
            for (; ; ++i, ++j)
            {
                if (substr[j] == 0)     // substr结束,找到了,返回true
                {
                    tail = i;           // 更新tail
                    return true;
                }
                if (substr[j] == '?')   // '?'则简单跳过
                {
                    ++j;
                    ++i;
                }
                if (substr[j] == '*')   // 蛋疼'*'出现,其他写好了就在这卡将近半小时有木有!dbg了很久啊!!
                {
                    char strTmp[255];  
                    StrCpy(strTmp, src, i, strlen(src));                    // strTmp保存遇到'*'时的src剩余的子串
                    Reverse(strTmp, 0, strlen(strTmp) - 1);                 // strTmp倒置,方便从后往前比,满足最大匹配

                    char substrTmp[255];
                    StrCpy(substrTmp, substr, ++j, strlen(substr));
                    Reverse(substrTmp, 0, strlen(substrTmp) - 1);           // 为了倒置比较,这个也要倒置

                    int headTmp = 0, tailTmp = 0;
                    if (FindSubstr(strTmp, substrTmp, headTmp, tailTmp))    // 如果在剩余的src发现匹配
                    {                                                       // 我用递归了哎,一直觉得递归老难了
                        tail = strlen(src) - headTmp;                       // 尾值更新
                        return true;                                        // 找到返回true
                    }
                }
                if (substr[j] == 0)         // substr结束,找到了,返回true
                {
                    return true;
                }
                if (substr[j] != src[i])    // 有不一样的,没找到
                {
                    break;
                }
            }
            i = head;                       // 没找到就回归“很久前的上一步”接着找
            j = 0;
        }
    }

    return false;   // src[i]都等于0了,真心没找到,返回false罢
}

// 需要实现的函数
void Replace(char *src, char *substr, char *replace, char *output)
{	
    int head = 0, tail = 0;
    if (!FindSubstr(src, substr, head, tail))
    {
        cout << "Can't find" << endl;
        return ;
    }        

    stringstream ss;
    int i = 0;
    for (i = 0; i < head; ++i)          // substr前的src
    {
        ss << src[i];
    }
    for (; *replace != 0; ++replace)    // substr替换为replace
    {
        ss << *replace;
    }
    for (i = tail; src[i] != 0; ++i)    // substr后的src
    {
        ss << src[i];
    }

    string s;
    ss >> s;
    for (i = 0; i < s.length(); ++i)    // 搞定output
    {
        output[i] = s[i];
    }
    output[i] = 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值