在数组中找到第一个pseudopalindrome

时间:2017-11-12 09:24:03

标签: c binary-search palindrome

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

#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;
}

该程序停止执行。问题可能是二进制搜索,因为每个函数都执行得很好。但这个二进制搜索有什么问题?或者还有什么可以打破代码?

2 个答案:

答案 0 :(得分:0)

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

编辑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;
}

答案 1 :(得分:0)

不是一个真正的答案,但评论中的代码很难阅读。

您也可以尝试简化代码;为一个回文制作一些代码是非常令人惊讶的;你重新实现的一些函数是标准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;
}