C substrings / C string slicing?

vxqlmq5t  于 2023-04-11  发布在  其他
关注(0)|答案(7)|浏览(142)

大家好!我正在尝试写一个程序,检查一个给定的文本字符串是否是回文(为此,我做了一个名为is_palindrome的函数),如果它的任何子字符串是回文,我不知道什么是最佳的方法来做到这一点:
例如,对于字符串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中以类似的方式使用?

vxf3dgd4

vxf3dgd41#

这是我用来在C中获取字符串片段的一个行程序。

void slice(const char *str, char *result, size_t start, size_t end)
{
    strncpy(result, str + start, end - start);
}

非常简单,因为你已经检查了边界并确保了end〉start。

ar5n3qh5

ar5n3qh52#

这个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$
vx6bjr1n

vx6bjr1n3#

没有你得自己写

khbbv19g

khbbv19g4#

为了检查字符串,您需要提供要检查的字符数,以便检查回文:

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))
    {
    ...
    }
 }

免责声明:未编译。

zzzyeukh

zzzyeukh5#

老实说,你不需要一个字符串切片函数来检查子字符串中的回文:

/* 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作为缓冲区大小。
  • strncpy可能根本不会终止字符串,使dest[n - 1]等于src[n - 1],因此您需要自己添加一个null终止符以防万一。如果n大于src字符串长度,则dest将使用null终止符填充,直到n字节被写入。
  • 如果需要,strslice将复制最多n字节,如strncpy,并且需要一个额外的字节用于空终止符,这意味着最多需要n+1字节。它不会像strncpy那样浪费时间编写不必要的空终止符。这可以被认为是“轻量级strlcpyn的含义略有不同,可以用于结果字符串长度无关紧要的地方。

如果需要,还可以创建一个memslice函数,这将允许嵌入空字节,但它已经作为memcpy存在。

k3fezbri

k3fezbri6#

在任何标准的C库中都没有任何内置的函数/方法可以处理这个问题。但是,你可以想出自己的方法来做同样的事情。

ycggw6v2

ycggw6v27#

使用https://www.github.com/madhukumarseshadri/slice进行切片。你可以使用./slice madhukumar 0:5来得到madhu。

相关问题