【问题标题】:Find a first pseudopalindrome in the array在数组中找到第一个伪回文
【发布时间】:2017-11-12 09:24:03
【问题描述】:

我有一个字符串数组,我想在数组中为每个字符串(如果有的话)找到第一个伪回文。所以我决定首先对我的数组进行排序,然后反转单词并对反转的单词进行二进制搜索。所以这就是我到目前为止所拥有的:

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

char len(char *x){
char len = 0;

while (*x != '\0'){
    x++;
    len++;
}

return len;
}

char compare(char *x, char *y){
char x0 = &x;
char y0 = &y;
while (*x != '\0'){
    if (tolower(*x) < tolower(*y)) return -1;
    if (tolower(*x) > tolower(*y)) return 1;
    x++;
    y++;
}
// if we are here it means that strings are equal (case insensitive)
x = &x0;
y = &y0;
while (*x != '\0'){
    if (*x > *y) return -1;
    if (*x < *y) return 1;
    x++;
    y++;
}
// strings are equal (case sensitive)
return 0;
}


char *reverse(char *x){
int i, j;
char temp, *rev = NULL;

rev = malloc(sizeof(char)*(len(x)+1));
rev = strcpy(rev,x);
i = 0;
j = len(x) - 1;
while (i < j){
    temp = rev[i];
    rev[i] = x[j];
    rev[j] = temp;
    i++;
    j--;
}

return rev;
}

int binsearch(char *x, char *A, int len){
int l, r, m, index;

l = 0;
r = len - 1;
index = -1;
while (l <= r){
    m = (l + r) / 2;
    if (compare(x, A[m]) == 0){
        index = m;
        r = m - 1;
    }
    else if (compare(x, A[m]) == -1) r = m - 1;
    else l = m + 1;
}

return index;
}
int main()
{

int n, i, j, k, fnd;
char T[10000][101], temp[101];

scanf("%d", &n);
for (i = 0; i < n; i++){
    scanf("%s", &T[i]);
}

for (i = 1; i < n; i++){
    strcpy(temp, T[i]);
    j = i - 1;
    while (j >= 0 && compare(T[j], temp) == 1){
        strcpy(T[j+1], T[j]);
        j--;
    }
    strcpy(T[j+1], temp);
}

for (i = 0; i < n; i++){
    fnd = binsearch(reverse(T[i]), T, n);
    printf("%d", fnd);
}
return 0;
}

此程序停止执行。问题可能在于二进制搜索,因为之前的每个函数都执行得很好。但是这个二分搜索有什么问题呢?或者还有什么可以破解密码?

【问题讨论】:

  • 请修正缩进
  • 回文是一个与自身相反的字符串。两个相互反转的不同字符串不是回文。请弄清楚术语。
  • 你不需要写你的len函数。 C 有一个名为 strlen 的内置函数,它完全按照您编写的方式进行操作。
  • 1.启用编译器警告并将其视为错误。 2. 阅读 strcpy 的手册。它需要什么头文件? 3. 阅读那个 heder 文件的概要。它有你可能想要使用的功能吗?
  • 您应该写一个问题,专门询问您收到的错误/警告。不要为此使用 cmets。顺便还有more errors than you cite

标签: c binary-search palindrome


【解决方案1】:

导致问题的返回类型..对于二进制搜索没有提到返回类型

编辑 1. 但是你没有在它的声明中提到函数的返回类型

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

char len(char *x){
char len = 0;

while (*x != '\0'){
    x++;
    len++;
}

return len;
}

char compare(char *x, char *y){
char* x0 = x;
char* y0 = y;
while (*x != '\0'){
    int a0 = tolower(*x);
    int b0 = tolower(*y);
    if ( a0 < b0) 
    return -1;
    if ( a0 > b0) 
    return 1;
    x++;
    y++;
}
// if we are here it means that strings are equal (case insensitive)
x = x0;
y = y0;
while (*x != '\0'){
    if (*x > *y) return -1;
    if (*x < *y) return 1;
    x++;
    y++;
}
// strings are equal (case sensitive)
return 0;
}


char *reverse(char *x){
int i, j;
char temp, *rev = NULL;

rev = malloc(sizeof(char)*(len(x)+1));
rev = strcpy(rev,x);
i = 0;
j = len(x) - 1;
while (i < j){
    temp = rev[i];
    rev[i] = x[j];
    rev[j] = temp;
    i++;
    j--;
}

return rev;
}

int binarysearch(char *x,char A[][101], int len){
int l, r, m, index;

l = 0;
r = len - 1;
index = -1;
while (l <= r){
    m = (l + r) / 2;
    if (compare(x, A[m]) == 0){
        index = m;
        r = m - 1;
    }
    else if (compare(x, A[m]) == -1) r = m - 1;
    else l = m + 1;
}

return index;
}
int main()
{

int n, i, j, k, fnd;
char T[10000][101], temp[101];

scanf("%d", &n);
for (i = 0; i < n; i++){
    scanf("%s", &T[i]);
}

for (i = 1; i < n; i++){
    strcpy(temp, T[i]);
    j = i - 1;
    while (j >= 0 && compare(T[j], temp) == 1){
        strcpy(T[j+1], T[j]);
        j--;
    }
    strcpy(T[j+1], temp);
}

for (i = 0; i < n; i++){
    fnd = binarysearch(reverse(T[i]), T, n);
    printf("%d", fnd);
}
return 0;
}

【讨论】:

  • 我从二分搜索返回一个索引
  • 我将其声明为int binsearch(已编辑)。复制时出错。
  • 它无法编译 - binsearch 声明中的错误:预期的声明说明符或 '...' 在 '(' 标记之前。
  • 只更新了一个警告..尝试解决它
  • 我没有收到任何警告。但是,当某些字母大小写不同时(例如 elpmaXe),程序不会捕捉到单词的反义词。我试图通过在二进制搜索中使用 tolower 函数来解决它,但它不起作用。
【解决方案2】:

不是真正的答案,但 cmets 中的代码读起来很痛苦。

您也可以尝试简化您的代码;有很多代码只是一个回文是相当令人惊讶的;您正在重新实现的某些函数是标准 c 的一部分(strlen、strcasecmp、strdup) 判断一个单词是否是回文的功能预计非常简单;这里是它可能的样本

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

bool isspeudopalindrom(const char *x){
    for (int i = 0; i < strlen(x) / 2; ++i) {
        if (tolower(x[i]) != tolower(x[strlen(x) - 1 - i]))
            return false;
    }
    return true;
}

int main(int argc, char *argv[])
{
    for (int i = 1; i < argc; i++){
        if (isspeudopalindrom(argv[i]))
            printf("palindrom\n");
        else
            printf("not palindrom\n");
    }
    return 0;
}

【讨论】:

    猜你喜欢
    • 2014-06-07
    • 2019-06-15
    • 2016-12-20
    • 2020-04-10
    • 2018-08-19
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 2021-03-25
    相关资源
    最近更新 更多