我需要编写一个函数,它接受两个char *
,一个包含一个字符串,另一个包含一组字符,它返回不包含任何字符的字符串的长度。
示例:
LenContainsAnyBut("abc", "def"); // returns 3
LenContainsAnyBut("abc", "b"); // returns 1
LenContainsAnyBut("x", "xyz"); // returns 0
LenContainsAnyBut("", "xyz"); // returns 0
这是我的实施:
unsigned int LenContainsAnyBut(const char *s, const char *search_chars) {
unsigned int len = 0;
while (*(s + len) != '\0' {
for (const char *search_char = search_chars; *seach_char != '\0'; ++search_char) {
if (*search_char == *(s + len)) {
return len;
}
}
++len;
}
return len;
}
有什么需要改进的吗?我更喜欢“数组表示法”,即s[0]
而不是s + 0
,但在此作业中不允许使用。
修改
Sry,不知何故设法完全搞砸我的代码>。<。
答案 0 :(得分:1)
要改变的一件事是len在代码中总是为0,你应该在while内部的for循环之后增加len。
其他小错误是你在len的声明中缺少't'(unsigned in应该是unsigned int)。
我也相信在for循环中你正在改变指针值本身,这只会使s的第一个字符被测试,当测试s * search_chars的其他字符总是等于“/ 0 “尝试在for循环中使用像len这样的整数
答案 1 :(得分:1)
如果您正在使用8位字符,则可以避免嵌套循环。首先确保s
和sc
(search_chars
)类型为unsigned char *
(不是普通char *
!)然后:
unsigned char set[32] = "";
size_t l=0;
for (; *sc; sc++) set[*sc/8] |= 1U<<*sc%8;
for (; *s; s++) l += 1-(set[*s/8]>>*s%8 & 1);
答案 2 :(得分:1)
发布的代码甚至没有编译,并且通过明显的修复,它将进入一个永恒的循环。
话虽如此,我会使用strchr()
编写此函数。
答案 3 :(得分:1)
如果您想改善长字符串和/或长排除集的运行时间,那么您可以尝试利用将字符用作数组索引的功能,并创建一个数组来表示允许的字符集/不允许你的字符串。
如果你创建一个长度为256的数组,为所有元素初始化为1(元素0除外,因为我认为你必须假设它总是被排除,因为没有办法在排除字符串中表示它,因为这是一个C字符串),然后遍历你的排除集字符串,将其中的每个字符转换为无符号(字符在某些系统上签名,但它们需要无符号才能使其工作)并设置由该字符索引的字节到0。
在此结尾处,您有一个查找表,可以让您快速判断字符是否为字符串的结尾,运行时间为O(n + m)而不是O(n * m)。
答案 4 :(得分:0)
使用此作业部分来提高我在C中编程的能力有限。
如果问题有明显的答案,那么道歉,
但代码中的值是len的值随着s中的字符被“测试并传递”而增加
答案 5 :(得分:0)
我只是将其实现为:
#include <string.h>
unsigned int LenContainsAnyBut(const char *s, const char *search_chars)
{
return strcspn(s, search_chars);
}
......但是,嘿,那只是我;)