2017-08-26 116 views
4

以下是我编写的用于在字符串回文中查找缺失字符的代码,但我不知道如何从两侧检查字符串时如何查找必须打印的字符同时。查找字符串回文中缺少的字符

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    char s[100], m[100]; 
    fgets(s, 100, stdin); 
    int len = strlen(s); 
    int a, b; 

    for (int i = 0; i < strlen(s); i++) { 
     m[i] = s[len - i - 1]; 
    } 

    for (int i = 0, j = 0; i <= strlen(s), j <= strlen(s); i++, j++) { 
     if (isspace(m[j])) { 
      j++; 
     } 
     if (s[i] != m[j]) { 
      if (len % 2 == 0) { 
       printf("%c", m[j]); 
       break; 
      } else { 
       printf("%c", s[i]); 
       break; 
      } 
     } 
    } 
} 

输入:Malayaam
输出:l

输入:abcddcb
输出:a

+3

'I <= strlen的(S),J <= strlen的(S)'不会做你认为它应该。 – mch

+0

具有挑战性的测试案例“ZZxyxyxxyxyZZ”(删除左边的x)与“ZZxyxyyxyxyZZ”(删除右边的y)。 – chux

+0

@chux不错的一个。但我认为命名一个字母添加被接受的解决方案的问题“找到失踪的......” – Yunnosch

回答

2

假设总是有正好一个错误的回文,我建议看看下一个在每一面上写一封信,以决定两个不同的字母中哪一个是缺失的字母。

代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 

int main(void) 
{ 
    char s[100],m[100]; 
    fgets(s,100,stdin); 
    int len=strlen(s)-1; 
    int i,j; 


    for(i=0;i<len;i++) 
    { 
     m[i]=tolower((unsigned char)s[len-i-1]); 
     s[i]=tolower((unsigned char)s[i]); 
    } 

    for(i=0,j=0;i<len;i++,j++) 
    { 
     if(s[i]!=m[j]) 
     { 
      printf("%c != %c, ", s[i], m[j]); 
      if(s[i+1]==m[j]) 
      { printf("but %c == %c, %c should be inserted on the right.\n", s[i+1], m[j], s[i]); 
      } else if(s[i]==m[j+1]) 
      { printf("but %c == %c, %c should be inserted on the left.\n", s[i], m[j+1], m[j]); 
      } else 
      { printf("giving up.\n"); 
      } 
      break; 
     } 
    } 

    return 0; 
} 

注:

  • 我通过MCH和后来chqrlie和chux并入评论
  • 我添加了所有输入的lowercasing,以防止 “M”= “Malayaam”中的“M”
  • 我认为你的[mcve]不完整,所以我编辑了几件东西。
  • 我编辑了一个对于向后兼容较旧的C
    (例如,在for循环头内没有声明i)。
  • 只有一个错误的假设,从一些边缘情况下保护
+1

缺少标题'',应该''char'参数'tolower'和'isspace'作为tolower((unsigned char )s [i])','isspace((unsigned char)m [j])'... – chqrlie

+0

@chqrlie好点。不能相信我没有“Wall”我的代码... – Yunnosch

+1

也'我'我'我 chqrlie

2

减少问题的发生,通过识别输入可能具有后'\n'是不需要参加测试。

#include <ctype.h> 
#include <stdbool.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
    char s[100]; 
    fgets(s, sizeof s, stdin); 
    s[strcspn(s, "\r\n")] = '\0'; 
    size_t len = strlen(s); 

当字符串不是回文由于1“额外”的字符,以去除左侧或右侧字符可能不可辨别直到相当数量的剩余字符串的处理。代码需要考虑2条路径。

size_t mismatch; 
    if (is_palindrome(s, len, &mismatch)) { 
    puts("Palindrome"); 
    } else if (is_palindrome(s + mismatch + 1, len - mismatch*2 - 1, NULL)) { // skip left 
    printf("left <%c>\n", s[mismatch]); 
    } else if (is_palindrome(s + mismatch, len - mismatch*2 - 1, NULL)) { // skip right 
    printf("right <%c>\n", s[len - mismatch-1]); 
    } else { 
    puts("Not palindrome nor off by 1 palindrome"); 
    } 
} 

所有剩下就是让is_palindrome()

bool is_palindrome(const char *s, size_t len, size_t *mismatch) { 
    printf("<%s> %zu\n", s, len); 
    size_t i = 0; 
    while (i + 1 < len) { 
    if (tolower((unsigned char)s[i]) != // 
     tolower((unsigned char)s[len - 1])) { 
     if (mismatch) { 
     *mismatch = i; 
     } 
     return false; 
    } 
    i++; 
    len--; 
    } 
    return true; 
}