例如,对于字符串s =" abcdefg"它应首先检查" a",然后" ab"," abc"," abcd"等等,每个角色
In Python this is the equivalent of
s[:1], s[:2], ... (a, ab, ...)
s[1:2], s[1:3] ... (b, bc, ...)
我可以在C中以类似的方式使用哪种功能/方法?
答案 0 :(得分:6)
这个slice_str()
函数可以解决这个问题,其中end
实际上是结束字符,而不是像Python切片一样的结尾:
#include <stdio.h>
#include <string.h>
void slice_str(const char * str, char * buffer, size_t start, size_t end)
{
size_t j = 0;
for ( size_t i = start; i <= end; ++i ) {
buffer[j++] = str[i];
}
buffer[j] = 0;
}
int main(void) {
const char * str = "Polly";
const size_t len = strlen(str);
char buffer[len + 1];
for ( size_t start = 0; start < len; ++start ) {
for ( int end = len - 1; end >= (int) start; --end ) {
slice_str(str, buffer, start, end);
printf("%s\n", buffer);
}
}
return 0;
}
,当使用上述main()
函数时,输出:
paul@horus:~/src/sandbox$ ./allsubstr
Polly
Poll
Pol
Po
P
olly
oll
ol
o
lly
ll
l
ly
l
y
paul@horus:~/src/sandbox$
答案 1 :(得分:5)
没有;你必须自己写。
答案 2 :(得分:2)
为了检查字符串,您需要提供要检查的字符数以便检查回文:
int palindrome(char* str, int len)
{
if (len < 2 )
{
return 0;
}
// position p and q on the first and last character
char* p = str;
char* q = str + len - 1;
// compare start char with end char
for ( ; p < str + len / 2; ++p, --q )
{
if (*p != *q)
{
return 0;
}
}
return 1;
}
现在您需要为每个子字符串调用上面的函数(正如您所描述的那样,即始终从头开始),例如。
char candidate[] = "wasitaratisaw";
for (int len = 0; len < strlen(candidate); ++len)
{
if (palindrome(candidate, len))
{
...
}
}
免责声明:未编译。
答案 3 :(得分:1)
老实说,你不需要字符串切片功能来检查子串中的回文:
/* start: Pointer to first character in the string to check.
* end: Pointer to one byte beyond the last character to check.
*
* Return:
* -1 if start >= end; this is considered an error
* 0 if the substring is not a palindrome
* 1 if the substring is a palindrome
*/
int
ispalin (const char *start, const char *end)
{
if (start >= end)
return -1;
for (; start < end; ++start)
if (*start != *--end)
return 0;
return 1;
}
使用它,您可以创建以下内容:
int
main ()
{
const char *s = "madam";
/* i: index of first character in substring
* n: number of characters in substring
*/
size_t i, n;
size_t len = strlen (s);
for (i = 0; i < len; ++i)
{
for (n = 1; n <= len - i; ++n)
{
/* Start of substring. */
const char *start = s + i;
/* ispalin(s[i:i+n]) in Python */
switch (ispalin (start, start + n))
{
case -1:
fprintf (stderr, "error: %p >= %p\n", (void *) start, (void *) (start + n));
break;
case 0:
printf ("Not a palindrome: %.*s\n", (int) n, start);
break;
case 1:
printf ("Palindrome: %.*s\n", (int) n, start);
break;
} /* switch (ispalin) */
} /* for (n) */
} /* for (i) */
}
当然,如果你真的想要一个字符串切片函数仅用于输出(因为你在技术上不应该将size_t
转换为int
),并且你仍然希望能够格式化输出很容易,Paul Griffiths的答案应该足够好,或者你可以使用我的,甚至是strncpy
或非标准strlcpy
中的一个,尽管它们都有自己的优点和缺点:
/* dest must have
* 1 + min(strlen(src), n)
* bytes available and must not overlap with src.
*/
char *
strslice (char *dest, const char *src, size_t n)
{
char *destp = dest;
/* memcpy here would be ideal, but that would mean walking the string twice:
* once by calling strlen to determine the minimum number of bytes to copy
* and once for actually copying the substring.
*/
for (; n != 0 && *src != 0; --n)
*destp++ = *src++;
*destp = 0;
return dest;
}
strslice
实际上就像strncpy
和非标准strlcpy
的组合,尽管这三个函数之间存在差异:
strlcpy
会将复制的字符串缩短以在dest[n - 1]
添加空终止符,因此在添加空终止符之前复制n
个字节要求您传递n + 1
as缓冲区大小。strncpy
可能根本不会终止字符串,dest[n - 1]
等于src[n - 1]
,因此您需要自己添加一个空终结符以防万一。如果n
大于src
字符串长度,dest
将使用空终止符填充,直到写入n
字节为止。strslice
将复制到n
个字节,如strncpy
,并且将需要额外的字节用于空终止符,这意味着最多n+1
个字节是必要。它不会浪费时间编写不必要的空终止符strncpy
。这可以被认为是“轻量级strlcpy
”,n
的含义差别很小,可以在结果字符串长度无关紧要的情况下使用。如果需要,您还可以创建一个memslice
函数,这将允许嵌入的空字节,但它已经存在为memcpy
。
答案 4 :(得分:0)
任何标准C库中都没有可以处理此问题的内置函数/方法。但是,您可以提出自己的方法来完成此操作。
答案 5 :(得分:0)
这是我用来在C中获取字符串切片的一个衬里。
void slice(const char *str, char *result, size_t start, size_t end)
{
strncpy(result, str + start, end - start);
}
非常简单。 鉴于您已经检查了边界并确保结束>开始。