Как исправить эти ошибки в этой проблеме кода палиндрома, чтобы сказать, является ли она нечетной или четной - PullRequest
0 голосов
/ 06 июля 2019

Данная строка является палиндромом, вам нужно указать, что она является четным палиндромом (палиндром с четной длиной) или нечетным палиндромом (палиндром с нечетной длиной), в противном случае возвращается №

Этот код я пишу, но не получаюtrue output

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

int main(){
    int n ;
    char s[100000],b[100000];
    int count=0,d,h,i,t,j;

    if(count<1)
    {
        scanf("%d", &n);
        if(n<=50)
        {
            for(t=1;t<=n;t++)
            {
                i=0,j=0,h=0;

                scanf("%s", s);

                h=strlen(s)-1;
                if(h>=1&&h<=100000)
                {
                    for(i=0,j=h;i<=h&&j>=0; j--,i++)
                    {
                        b[i]=s[j];

                    } 

                    if(strcmp(s,b)==0)
                    {
                        if(h%2==0)
                        {
                            printf("YES EVEN");
                            printf("\n");
                        }
                        else
                        {
                            printf("YES ODD");
                            printf("\n");
                        }
                    }
                    else{
                        printf("NO");
                        printf("\n");
                    }
                }
            }       
        }
        count++;
    }
    return 0;
}
#include<string.h>
#include <stdio.h>

int main(){
    int n ;
    char s[100000],b[100000];
    int count=0,d,h,i,t,j;

    if(count<1)
    {
        scanf("%d", &n);
        if(n<=50)
        {
            for(t=1;t<=n;t++)
            {
                i=0,j=0,h=0;

                scanf("%s", s);

                h=strlen(s)-1;
                if(h>=1&&h<=100000)
                {
                    for(i=0,j=h;i<=h&&j>=0; j--,i++)
                    {
                        b[i]=s[j];

                    } 

                    if(strcmp(s,b)==0)
                    {
                        if(h%2==0)
                        {
                            printf("YES EVEN");
                            printf("\n");
                        }
                        else
                        {
                            printf("YES ODD");
                            printf("\n");
                        }
                    }
                    else{
                        printf("NO");
                        printf("\n");
                    }
                }
            }       
        }
        count++;
    }
    return 0;
}

Забудьте о синтаксической ошибке, найдите только логическую ошибку.

Я ожидаю, что на выходе будет

Ввод

3
abc
abba
aba

Вывод вашего кода

NO
YESODD
NO

Ожидаемый правильный вывод

NO
YESEVEN
YESODD

Я получаю истинный результат, когда я предоставляю одну строку не более того, но где ошибка.

Ответы [ 3 ]

0 голосов
/ 06 июля 2019

У вас есть ряд проблем, но ваша основная проблема в вашем обращении. Вы пытаетесь повернуть вспять с помощью:

    h=strlen(s)-1;
    if(h>=1&&h<=100000){
     for(i=0,j=h;i<=h&&j>=0; j--,i++) {
        b[i]=s[j];
    }

Это не удастся для strlen(s) == 1, не гарантирует нулевое завершение, и поскольку вы используете h=strlen(s)-1;, ваше h в if (h % 2 == 0) приведет к противоположному определению EVEN и ODD. Вместо этого вам нужно:

#define MAXC 100000     /* if you need a constant, #define one (or more) */
...
    h = strlen (s);             /* h must be strlen(s) - not - 1 */
    if (h >= 1 && h < MAXC) {   /* now loop j=h-1; j < h  times */
        for (i = 0, j = h-1; i < h && j >= 0; j--,i++)
            b[i] = s[j];
        b[i] = 0;               /* and ensure b is nul-terminated */

( примечание: код с достаточным интервалом намного легче читать и отлаживать)

Далее вам не удается проверить возвращение каждого вызова на scanf, вместо этого вслепую используя переменные без указания того, был ли ваш ввод успешным - рецепт для Неопределенное поведение . Вы должны проверить КАЖДЫЙ пользовательский ввод, например,

    if (scanf ("%d", &n) != 1 || n > 50) {
        fputs ("error: invalid integer or out-of-range.\n", stderr);
        return 1;
    }

    while (n-- && scanf ("%s", s) == 1) {

Простой выбор логического факторинга вашего кода полностью исключает необходимость в переменных t и d. Обратите внимание, что ваши условия для n: (1) он действителен, и (2) он 50 или меньше. Они могут быть объединены в одну проверку. То же самое относится к циклу n раз при чтении слов в s.

При внесении этих изменений ваш код упрощается до:

#include <stdio.h>

#define MAXC 100000     /* if you need a constant, #define one (or more) */

int main (void)
{
    char s[MAXC];
    int n;

    if (scanf ("%d", &n) != 1 || n > 50) {
        fputs ("error: invalid integer or out-of-range.\n", stderr);
        return 1;
    }

    while (n-- && scanf ("%s", s) == 1) {
        char b[MAXC];               /* b is only needed within loop */
        int h = strlen (s), i = 0, j;   /* as are h, i, j, no - 1 for h */
        if (h >= 1 && h < MAXC) {   /* now loop j=h-1; j < h  times */
            for (i = 0, j = h-1; i < h && j >= 0; j--,i++)
                b[i] = s[j];
            b[i] = 0;               /* and ensure b is nul-terminated */

            if (strcmp (s, b) == 0) {
                if (h % 2 == 0)
                    printf ("YES EVEN\n");
                else
                    printf ("YES ODD\n");
            }
            else
                printf ("NO\n");
        }
    }
    return 0;
}

, который теперь обеспечивает проверку палиндрома и длину ODD или EVEN, которую вы искали, например,

Пример использования / Вывод

$ echo "5 abcba abccba abcdba a aa" | ./bin/pdromerefmt
YES ODD
YES EVEN
NO
YES ODD
YES EVEN

Необходимо дополнительно защитить границы массива s, добавив модификатор field-width для преобразования "%s", например. "%99999s", что устраняет необходимость проверять h <= 100000 (что уже вызвало бы Неопределенное поведение , если ввод был 100000 символов или больше). Нет необходимости проверять h >= 1, поскольку ограничения цикла ничего не делают с h = 0 - но гарантируют пустую строку.

Благодаря дополнительным настройкам и защите границ массива ваш цикл упрощается до:

    while (n-- && scanf ("%99999s", s) == 1) {
        char b[MAXC];                   /* b is only needed within loop */
        int h = strlen(s), i = 0, j = h;/* as are h, i, j, no -1 for h */
        while (j--)             /* must loop j times, regardless */
            b[i++] = s[j];      /* reversing characters in s in b */
        b[i] = 0;               /* and ensure b is nul-terminated */

        if (strcmp (s, b) == 0) {
            if (h % 2 == 0)
                printf ("YES EVEN\n");
            else
                printf ("YES ODD\n");
        }
        else
            printf ("NO\n");
    }
0 голосов
/ 06 июля 2019

Забудьте о синтаксической ошибке, найдите только логическую ошибку.

Это то, для чего нужны карандаши и бумаги (или, может быть, ваша резиновая утка), чтобы выяснить алгоритм и логически следовать его шагам.,У вас есть полная программа и большое количество тестов для ее тестирования.Теперь пришло время устранить каждую найденную ошибку, начиная с из синтаксических ошибок, которые «легко» обнаруживаются во время компиляции.

В опубликованных сообщениях уже достаточно ответов о недостатках.кода, но есть по крайней мере одна вещь, которая еще не рассмотрена, хотя на самом деле это не ошибка или логическая ошибка.

Опубликованный алгоритм для каждого теста выполняет следующее:

  • Прочитайте слово (с scanf).

  • Найдите его размер (с strlen).

  • Создайте обратную его копию (используя цикл for).

  • Сравните копию с оригиналом, чтобы проверить палиндромность (с strcmp).

Почему все эти копии и обход массива?Узнав длину слова, вы можете просто сравнить левую часть строки с правой.

#include <stdio.h>
#include <stdbool.h>
#include <assert.h>

#define MAX_CHARS_IN_STR  100000
#define MAX_N_TESTS           50

// Performs the check without copying the the string
// length: size of the word
bool is_palindrome(size_t length, const char *str);

#define STRINGIFY_IMPL(x) #x
#define STRINGIFY(x) STRINGIFY_IMPL(x)
#define STR_WIDTH_FMT(x) "%" STRINGIFY(x) "s"

int main(void)
{
    int n_words;
    if ( scanf("%d", &n_words) != 1  ||  n_words < 1  ||  n_words > MAX_N_TESTS)
    {
        fprintf(stderr, "Error: the input is not a valid integer between 1 and %d.",
                MAX_N_TESTS);
        return 1;
    }

    int n_chars;
    // Allocates an array big enough (including the null-terminator)
    char word[MAX_CHARS_IN_STR + 1];
    // It will use an array of two pointers instead of another if-else
    const char *even_or_odd_str[] = { "IS EVEN", "IS ODD" };
    while ( n_words-- )
    {
        // consume whitespace characters left in the input
        scanf(" ");

        // reads the string up to its maximum width or until the first whitespace.
        // The macro expands to "%100000s" and that literal will be concatenated to "%n",
        // which returns the number of characters read.
        if ( scanf(STR_WIDTH_FMT(MAX_CHARS_IN_STR) "%n", word, &n_chars) != 1 )
        {
            fputs("Error: unable to read word.", stderr);
            break;
        }

        if ( is_palindrome(n_chars, word) )
            puts(even_or_odd_str[n_chars % 2]);
        else
            puts("NO");
    }
}

bool is_palindrome(size_t n, const char *str)
{
    assert(n && str);
    size_t i = 0, j = n - 1;
    while ( i < j  &&  str[i] == str[j] )
    {
        ++i;
        --j;
    }
    // It's a palindrome only if the two indices met halfway
    return i >= j;
}
0 голосов
/ 06 июля 2019
  1. При создании строки b вы забыли добавить завершающий символ \0
  2. При проверке четности вы используете h%2.Но h - это strlen(s)-1.Поэтому вам нужно установить нечетное значение, если h%2 == 0

Соответствующие изменения показаны ниже

for(i=0,j=h;i<=h&&j>=0; j--,i++)
{
    b[i]=s[j];

} 
b[h+1] = '\0';

if(strcmp(s,b)==0)
{
    if(h%2!=0)
    {
        printf("YES EVEN");
        printf("\n");
    }
    else
    {
        printf("YES ODD");
        printf("\n");
    }
}

Забудьте о синтаксической ошибке, найдите только логическую ошибку.

Я считаю такое утверждение очень неправильным.Если вы не исправите синтаксис, вы не можете смотреть на него логически.Также правильный отступ действительно помогает в отладке кода и поиске ошибок самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...