程式解決了什么問題:
從用戶輸入中查找回文。
需要調整的問題:如果我們忽略標點符號和空格,
如何讓代碼接受像 Palindrome 這樣的句子。Rise to vote sir!如果你倒著讀它會是一樣的!
我嘗試過的事情: 我嘗試將字符 az、AZ 和 0-9 保存到字符型別陣列中,然后繼續處理它的邏輯。但無濟于事。
我希望有人能建議在哪里調整以下 C 代碼段,使其可以處理短語或句子,在代碼邏輯的計算中不包含空格、標點符號和特殊字符。
/* Search for a palindrome */
#include <stdio.h>
#include <ctype.h>
#define EOL '\n'
#define TRUE 1
#define FALSE 0
int main()
{
int tag, count, countback, flag, loop = TRUE;
char letter[80];
/* main loop */
while (loop)
{
/* anticipated palindrome */
flag = TRUE;
/* read in the text */
printf("\nPlease enter a word, phrase, or sentence below:\n");
for (count = 0; (letter[count] = getchar()) != EOL; count)
;
/* test for end of program keyword END */
if ((toupper(letter[0]) == 'E') && \
(toupper(letter[1]) == 'N') && \
(toupper(letter[2]) == 'D'))
break;
tag = count - 1;
/* carry out the search */
for ((count = 0, countback = tag); count <= tag / 2; ( count, --countback))
{
if (letter[count] != letter[countback])
{
flag = FALSE;
break;
}
}
/* display message */
for (count = 0; count <= tag; count)
putchar(letter[count]);
if (flag)
printf(" --> IS a Palindrome!\n\n");
else
printf(" --> is NOT a Palindrome.\n\n");
} /* end of main loop */
return 0;
}
uj5u.com熱心網友回復:
在回圈中,添加子回圈,使得 while!isalnum(letter[count])和!isalnum(letter[countback])為真;分別遞增count和遞減countback。例如:
// skip non-alphanum on left
while( !isalnum(letter[count]) )
{
count ;
}
// skip non-alphanum on right
while( !isalnum(letter[countback]) )
{
countback-- ;
}
但是,這樣做會破壞您的外部回圈,因為您不能再假設字串的中心是可能的回文的中心。無論如何,最好簡單地測驗一下count > countback。例如:
for( int count = 0, countback = tag ;
count < countback;
count, --countback )
并且因為您隨后修改了回圈中的控制變數,所以您需要在“非回文”測驗中添加一個檢查,并且您還想忽略大小寫:
if( count < countback &&
toupper(letter[count]) !=
toupper(letter[countback])
{
flag = FALSE ;
}
該測驗實際上可以簡化:
if( count < countback )
{
flag = (toupper(letter[count]) ==
toupper(letter[countback]) ;
}
為了避免 ctype.h 函式的未定義行為,letter陣列也應該有型別unsigned char。
這是你問的最小的“調整”。更多的是評論而不是答案的一部分,但我建議對結構、評論、命名、范圍和 I/O 進行一些“風格”改進;我重新實作您的代碼以獲得它的價值:
// Test for a palindrome
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int main()
{
bool terminate = false ;
while( !terminate )
{
// read in the text
unsigned char text[80] ;
printf("\nPlease enter a word, phrase, or sentence below:\n");
fgets( text, sizeof(text), stdin ) ;
int text_length = strlen(text) ;
if( text[text_length-1] == '\n')
{
text_length-- ;
text[text_length] = 0 ;
}
// test for end of program keyword END
terminate = text_length == 3 &&
toupper(text[0]) == 'E' &&
toupper(text[1]) == 'N' &&
toupper(text[2]) == 'D' ;
if( !terminate )
{
// Test for not palindrome
bool is_palindrome = true ;
for( int count = 0, countback = text_length - 1 ;
is_palindrome && count < countback;
count , countback-- )
{
// skip non-alphanum on left
while( count < countback &&
!isalnum(text[count]) )
{
count ;
}
// skip non-alphanum on right
while( count_back > count &&
!isalnum(text[countback]) )
{
countback-- ;
}
// If not at or past middle...
if( count < countback )
{
// Test for left/right match
is_palindrome = (toupper(text[count]) ==
toupper(text[countback])) ;
}
}
// Output test and test result.
printf( "%s --> %s a Palindrome!\n\n",
text,
(is_palindrome ? "IS" : "IS NOT") ) ;
}
}
return 0;
}
這也允許在不終止的情況下測驗"end ?dne"和之類的字串。"end of the world"
此外,將處理與 I/O 分開總是一個好主意。為此,您可以創建一個函式:
bool isPalindrome( const char* str )
{
const unsigned char* text = (const unsigned char*)str ;
size_t text_length = strlen(str) ;
if( text_length == 0u ) return true ;
// Test for not palindrome
bool is_palindrome = true ;
for( size_t count = 0, countback = text_length - 1;
is_palindrome && count < countback;
count , countback-- )
{
// skip non-alphanum on left
while( count < countback &&
!isalnum(text[count]) )
{
count ;
}
// skip non-alphanum on right
while( countback > count &&
!isalnum(text[countback]) )
{
countback-- ;
}
// If not at or past middle...
if( count < countback )
{
// Test for left/right match
is_palindrome = (toupper(text[count]) ==
toupper(text[countback])) ;
}
}
return( is_palindrome ) ;
}
然后在主體中,您將擁有:
bool is_palindrome = isPalindrome( text ) ;
printf("%s --> %s a Palindrome!\n\n", text, (is_palindrome ? "IS" : "IS NOT"));
甚至:
printf( "%s --> %s a Palindrome!\n\n", text,
(isPalindrome( text ) ? "IS" : "IS NOT") ) ;
uj5u.com熱心網友回復:
這是您的內部回圈的修改版本:
// Test for not palindrome
bool is_palindrome = true;
int count = 0;
int countback = text_length - 1;
while (is_palindrome && count < countback) {
unsigned char c1 = text[count ];
if (isalnum(c1)) {
unsigned char c2 = text[countback--];
if (isalnum(c2)) {
is_palindrome = (toupper(c1) == toupper(c2));
} else {
count--;
}
}
}
這是一個(幾乎)沒有冗余測驗的函式版本:
#include <ctype.h>
#include <stdbool.h>
#include <string.h>
bool is_palindrome(const char *text) {
size_t i = 0, j = strlen(text);
unsigned char c1, c2;
while (i < j) {
while (!isalnum(c1 = text[i ])) {
if (i == j)
return true;
}
while (!isalnum(c2 = text[--j])) {
if (i == j)
return true;
}
if (toupper(c1) != toupper(c2))
return false;
}
return true;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/532233.html
標籤:数组C空间回文标点
上一篇:1 (1-2) (1-2 3) (1-2 3-n)...之和,其中偶數為-k,奇數為 k
下一篇:使用calloc賦值
