C 如何使用双指针定义字符串isAlindrome?

C 如何使用双指针定义字符串isAlindrome?,c,C,Input:s=“一个人、一个计划、一条运河:巴拿马” 输出:true 解释:“amanaplanacanalamana”是一个回文。 bool isPalindrome(char * s){ if(strlen(s) == 0) return true; int m = 0; for(int i = 0; i < strlen(s); i++) if(isalnum(s[i])) s[m++] = tolower(s[i]); int

Input:s=“一个人、一个计划、一条运河:巴拿马”

输出:true

解释:“amanaplanacanalamana”是一个回文。

bool isPalindrome(char * s){
    if(strlen(s) == 0) return true;

    int m  = 0;
    for(int i = 0; i < strlen(s); i++)
        if(isalnum(s[i])) s[m++] = tolower(s[i]);
    int i = 0;
    while(i<m)
        if(s[i++] != s[--m]) return false;

    return true;
}
bool isPalindrome(char*s){
如果(strlen=0)返回true;
int m=0;
对于(int i=0;i而(i只需像这样定位两个指针

char* first = someString;
char* end = someString + strlen(s) - 1;  
#include <stdio.h>
#include <string.h>

int palindrome(char* str)
{
  char* start = str;
  char* end = str + strlen(str) - 1;
  for (; start < end; ++start, --end )
  {
      if (*start != *end)
      {
          return 0;
      }
  }
  return 1;
}

int main()
{
    printf("palindrome: %d\n", palindrome("1331"));
    printf("palindrome: %d\n", palindrome("132331"));
    printf("palindrome: %d\n", palindrome("74547"));

    return 0;
}
现在,要使它成为回文,
first
end
指向的内容必须相同

e.g. char someString[] = "1331";
因此,您在第一次迭代中*first==*last,即“1”

现在,将指针朝着彼此移动,直到没有任何东西可供比较或当它们不同时

++first, --end;

now *first and *last point to '3'
以此类推,检查它们是否指向同一个,或者是否相互传递,这是一个回文

像这样的

char* first = someString;
char* end = someString + strlen(s) - 1;  
#include <stdio.h>
#include <string.h>

int palindrome(char* str)
{
  char* start = str;
  char* end = str + strlen(str) - 1;
  for (; start < end; ++start, --end )
  {
      if (*start != *end)
      {
          return 0;
      }
  }
  return 1;
}

int main()
{
    printf("palindrome: %d\n", palindrome("1331"));
    printf("palindrome: %d\n", palindrome("132331"));
    printf("palindrome: %d\n", palindrome("74547"));

    return 0;
}
#包括
#包括
整型回文(char*str)
{
char*start=str;
char*end=str+strlen(str)-1;
对于(;开始<结束;++开始,--结束)
{
如果(*开始!=*结束)
{
返回0;
}
}
返回1;
}
int main()
{
printf(“回文:%d\n”,回文(“1331”);
printf(“回文:%d\n”,回文(“132331”);
printf(“回文:%d\n”,回文(“74547”);
返回0;
}
您应该添加错误检查,因为函数中没有错误检查

我的代码的运行时间是173ms。我的导师建议我使用两个指针来提高性能和内存使用率,但我不知道从哪里开始

它已经在O(n)中运行,因此您无法降低时间复杂度(除了对
strlen
的迭代调用,请参见下文),尽管还有一些改进性能的空间

您的函数不声明任何数组,只使用了几个变量,内存使用量完全不依赖于输入大小。内存使用量已经是O(1)并且非常低,因此这不是真正的问题

但是,如果您想使用指针,这里有一个:

bool isPalindrome(char * s){
    char *end = s + strlen(s);
    char *a = s;
    char *b = end-1;
    
    while(true) {
        
        // Skip characters that's not alphanumeric
        while( a != end && !isalnum(*a) ) a++;
        while( b != s && !isalnum(*b) ) b--;

        // We're done when we have passed the middle
        if(b < a) break;
       
        // Perform the check
        if(tolower(*a) != tolower(*b)) return false;

        // Step to next character
        a++;
        b--;
    }

    return true;
}
应该是

size_t len = strlen(s);
for(size_t i = 0; i < len/2; i++)
size\u t len=strlen;
对于(大小i=0;i

我对您的代码的另一个评论是它更改了输入字符串。这不是必需的。如果我有一个名为
isPalindrome
的函数,我希望它只检查字符串是否是回文。依我看,签名应该是
bool isPalindrome(const char*s)请不要删去部分问题。关于内存使用的注释是问题的一部分。它是否是一个合理的问题可以在回答或评论中得到解决。提示:你不需要遍历整个字符串,你可以在中间停止。我要写一个正确的答案,但是我想知道运行时会是怎样的。由于其他更改而导致的更改。例如,仅计算
strlen(s)
一次(而不是
strlen(s)+1次),撒上一些
const
,等等。也许编译器会将其优化为等效的,但我会研究这类事情,即使根本不改变算法。虽然这是一个很好的方法,但值得注意混淆名称。您答案中的
s
与问题中的
s
不一致n、 此处的回文检查首先剥离非字母数字字符,这意味着不能通过添加字符串来计算
最后一个
指针
。可以发布整个编辑的代码吗?这对我和其他初学者更好地理解整个过程非常有帮助。我很感激。@MingfengLi sure==29==ERROR:AddressSanitizer:pc 0x562272a15546 bp 0x7ffea9aaa0b0 sp 0x7ffea9aa0a0上的地址0x602000000072堆缓冲区溢出。您的代码存在缓冲区溢出问题,并且只通过了2次测试。@MingfengLi认为我现在已经解决了是的,它现在工作得很好。我仍然很好奇为什么我们需要在while循环结束时增加a和减少b。@MingfengLi因为否则你只能站着still@MingfengLi这回答了你的问题吗?还是什么还不清楚?