簡體   English   中英

C中回文函數的意外輸出

[英]Unexpected output from palindrome function in C

我已經編寫了此函數isPalindrome,該函數旨在從單獨的函數中獲取字符串輸入,如果它是回文,則返回1,否則返回0。 輸入的內容可以是任何字符,也可以有大寫字母,該函數用於對這些字符進行排序,並純粹根據字母字符檢查回文是否是回文。

我已經有一段時間了,我無法弄清楚出了什么問題,整個功能都在下面,但是我無法理解它給我的輸出,有時它會完全跳過最后的else語句,並且停止循環,我不知道為什么。 當連續輸入兩個非字母字符時,變量a或b不會增加兩次,而是將其發送到最后的else語句並返回錯誤的值。

我正在嘗試編寫此函數,而不將任何信息也復制到單獨的數組中。

int isPalindrome(char s[])
{
int logic;
int a = 0;
int b = 0;
int num = 0;
int count = 0;

while ( s[b]!='\0' )
{
    if ( isalpha(s[b]) != 0 )
    {
        num++;
    }
    b++;
}

b = b - 1;

printf("The number of characters is: %d\n", b);
printf("The number of alpha characters is: %d\n", num);

while ( count < num/2 )
{

    if ( !isalpha(s[a]) || s[a] == ' ')
    {
        a++;
    }
    else
    {
        count++;
    }
    if ( !isalpha(s[b]) || s[b] == ' ')
    {
        b--;
    }

    if ( toupper(s[a]) == toupper(s[b]) )
    {

        printf("s[%d]: %c | s[%d]: %c\n", a, toupper(s[a]), b, toupper(s[b]));

        a++;
        b--;

        if ( a == b )
        {
            logic = 1;
        }
    }
    else
    {
        logic = 0;
        break;
    }
}

   return logic;
}

有多個錯誤(1)邏輯必須初始化為1(2)每次循環迭代僅檢查一個無效字符。

如果刪除以下代碼,它應該可以工作(我的意思是沒有有效的字符檢查)。

if ( !isalpha(s[a]) || s[a] == ' ')
{
    a++;
}
else
{
    count++;
}
if ( !isalpha(s[b]) || s[b] == ' ')
{
    b--;
}

要刪除無效字符,最好在進入循環之前執行此操作,或者檢查'a <b'而不是count / 2,然后繼續對無效字符進行如下操作。

logic=1;
while (a<b)
{
    if ( !isalpha(s[a]))
    {
        a++;
        continue;
    }

    if ( !isalpha(s[b]))
    {
        b--;
        continue;
    }

    if ( toupper(s[a]) == toupper(s[b]) )
    {
        printf("s[%d]: %c | s[%d]: %c\n", a, toupper(s[a]), b, toupper(s[b]));

        a++;
        b--;
    }
    else
    {
        logic = 0;
        break;
    }
}

 return logic;

看來您希望回文測試人員僅考慮字母字符,而忽略大小寫。 如果真是這樣,您的程序邏輯是錯誤的。

您有ab作為字符串的索引,其中a從頭開始, b從頭開始。 我認為最好將b設置為最后,然后開始工作循環,而不是計算必須執行的測試數量。 只要a < b為真,循環就會繼續:

int a = 0;
int b = strlen(s) - 1;

while (a < b)
{

在循環的身邊,你應該增加a ,如果s[a]不能是字母,和減量b如果s[b]是不是一個字母,只要a持續小於b

    while (a < b && !isalpha(s[a]))
    {
        ++a;
    }
    while (a < b && !isalpha(s[b]))
    {
        --b;
    }

如果在調整之后, a仍小於b ,則可以不考慮大小寫而比較s[a]s[b] 如果它們不相等,則字符串不是回文,因此我們可以從循環中中斷。 否則, a遞增, b遞減,循環繼續回到頂部:

    if (a < b &&  toupper(s[a]) != toupper(s[b]))
    {
        break;
    }
    ++a;
    --b;
}

如果循環結束並且a < b仍然為true,則意味着toupper(s[a]) != toupper(s[b]) ,因此該字符串不是回文,我們可以返回false。 否則,它是回文。 因此該函數可以返回以下事實:

if (a < b)
{
    return false;
}
else
{
    return true;
}
// or more succinctly: return !(a < b);

您的錯誤在導致“有效載荷”回文條件檢查的代碼中:

if ( toupper(s[a]) == toupper(s[b]) )

該檢查之前的代碼應該使ab處於s[a]s[b]均為字母的狀態。

您的代碼無法做到這一點:特別是,當您將一個字母與一個非字母甚至兩個非字母進行比較時,多個非字母字符的序列會使您進入一種狀態。

解決此問題的更簡單方法是將程序分為兩個階段。 第一階段將消除輸入字符串中的所有非字母; 第二階段將執行回文檢查。

復制輸入字符串,然后逐個字符地進行遍歷,僅將字母復制回字符串中。 您最終會得到一個比原始字符串短或相同長度的字符串。

現在回文檢查變得無足輕重了:從兩端開始,檢查是否有toupper直到兩端在中間相遇。 不要忘記釋放您的字符串副本!

您跳過非字母字符的代碼無法處理多個連續的非字母字符的情況。 您可以從預處理過程中知道有多少個字母字符,因此您需要用while循環替換if語句,並使else的主體成為無條件的。

我會自動在代碼中進行許多其他簡化。

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

static
int isPalindrome(char s[])
{
    int a = 0;
    int b = 0;
    int num = 0;
    int count = 0;

    while (s[b] != '\0')
    {
        if (isalpha(s[b++]))
            num++;
    }

    printf("The number of characters is: %d\n", b);
    printf("The number of alpha characters is: %d\n", num);

    while (count < num/2)
    {
        count++;
        while (!isalpha(s[a]))
            a++;
        while (!isalpha(s[b]))
            b--;

        if (toupper(s[a]) != toupper(s[b]))
            return 0;
        printf("s[%d]: %c | s[%d]: %c\n", a, toupper(s[a]), b, toupper(s[b]));
        a++;
        b--;
    }

    return 1;
}

int main(void)
{
    char line[256];
    while (fgets(line, sizeof(line), stdin) != 0)
    {
        line[strlen(line)-1] = '\0';
        printf("Input: <<%s>>\n", line);
        if (isPalindrome(line))
            puts("Palindrome");
        else
            puts("Not a palindrome");
    }
    return 0;
}

這適用於字母和非字母字符的錯誤序列。 它將空行和由所有非字母字符組成的行視為回文。 如果希望它們被拒絕,則可以在對字母字符數進行計數的循環之后,當字母字符數為零時報告“不是回文”,以解決該問題。 當檢測到字符串不能是回文字符串時,該代碼會盡早返回。 您可以在測試之前在循環中移動打印語句; 然后您將看到每個比較的結果,而不僅僅是成功的比較。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM