C 语言题目,造轮子,看谁的轮子最厉害,有牛奶奖励。

2017-06-22 03:14:00 +08:00
 NullMan

题目:

从字符串删除特定子字符串。

条件

这题目是从“ C 和 指针”这书看到的,条件三是我自己添加的。

函数原型:

void del_substr(char *str, const char *substr);

举例:

char str[] = "ABCDEFG";
char substr[] = "CDE";
del_substr(str, substr);

这个时候,str 的值就应该是"ABFG"。
如果 substr 为 “ CDG ”, 执行该函数,str 保持不变("ABCDEFG")

实现:

以下代码乃本人所写,虽然刚学 C, 但是仍然对此代码不满意,代码行数太多了,太绕了,不直接。直觉告诉我,还可以写得更精简。望各位赐教一下,多谢!

void del_substr(char *str, const char *substr) {
    int i = 0, j = 0;
    while (*(str+i)) {
        j = 0;
        while (*(substr+j) && *(substr+j) == *(str+i+j)) {
            j++;
        }
        if (! *(substr+j)) {
            break;
        }
        else {
            i++;
        }
    }
    if (! *(substr+j)) {
        while ((*(str+i) = *(str+i+j))) {
            i++;
        }
    }
}

奖励:

代码写得最简单,最精炼, 我请你喝牛奶。:)

4819 次点击
所在节点    C
46 条回复
XYxe
2017-06-22 03:18:52 +08:00
i,j 和下标没有什么区别啊,换成对应的指针更好一点
kyuuseiryuu
2017-06-22 03:21:04 +08:00
markdown 也是刚学的吧。
NullMan
2017-06-22 03:24:15 +08:00
@kyuuseiryuu 哈哈!你是怎么看出来的?
NullMan
2017-06-22 03:26:39 +08:00
@XYxe 是的,没什么区别。但是我想不出一个变量都不用还能保持简单的写法。
kyuuseiryuu
2017-06-22 03:29:23 +08:00
@NullMan 代码块用行内代码表示了。正确做法是三个反引号开头跟上语言名称,回车接代码块,回车接三个反引号结束。
NullMan
2017-06-22 03:32:08 +08:00
@kyuuseiryuu 我就是这么写的呀。不过我选的是 bash。
kyuuseiryuu
2017-06-22 03:37:10 +08:00
@NullMan 这就很尴尬了,果然。我用浏览器看就没问题,客户端就变成行内代码的样式了。哇~我要找个地洞钻进去!快,帮我挖个洞~逃~
yangff
2017-06-22 03:55:42 +08:00
yangff
2017-06-22 04:11:43 +08:00
RqPS6rhmP3Nyn3Tm
2017-06-22 04:37:59 +08:00
Void main {
Printf("九评 xxx");
Return 0;
}

真 轮子
geelaw
2017-06-22 04:58:47 +08:00
```c
/* 删除所有的匹配 */
void del_substr(char *str, char const *pattern)
{
char const *copy = str;
int match;
if (!str || !pattern || !*pattern)
return;
while (*copy)
{
for (match = 0; copy[match] && copy[match] == pattern[match]; ++match)
;
if (pattern[match]) *str++ = *copy++;
else copy += match;
}
*str = 0;
}
```

懒得验证了

限制于空间要求,没法写更聪明的代码,这个算法非常地慢
geelaw
2017-06-22 04:59:54 +08:00
另外没有理解“请你喝牛奶”是什么玩意儿
geelaw
2017-06-22 05:06:50 +08:00
如果你只要删除第一个匹配,可以只用一个 explicit 变量,用一个 int 作为匹配长度的记录,当找到匹配的时候,循环利用 pattern 指针作为复制源位置即可。
V3EX17
2017-06-22 07:39:19 +08:00
@BXIA 返回值不应该有吧😄
headmaster
2017-06-22 07:52:44 +08:00
Mark,到了公司写一个
nutting
2017-06-22 08:56:16 +08:00
喝牛奶,听起来有点邪恶
koebehshian
2017-06-22 09:14:13 +08:00
不能使用下标但却可以使用解引用,这两者没什么区别
nvmhi
2017-06-22 09:18:49 +08:00
@nutting 抓住一名怪蜀黍
headmaster
2017-06-22 09:28:44 +08:00
@NullMan 想了一下,你要的应该就是 BM 算法🙈
azh7138m
2017-06-22 09:35:42 +08:00
搞个 int64 当俩 int32 是不是也行?最后这个条件没啥意思呐;不让用数组下标是真的滑稽:)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/370191

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX