如何实现我的字谜和回文函数来检查用户输入的单词?

Posted

技术标签:

【中文标题】如何实现我的字谜和回文函数来检查用户输入的单词?【英文标题】:How can I implement my anagram and palindrome functions to check the words input by a user? 【发布时间】:2013-10-21 07:25:40 【问题描述】:

我之前得到了一些帮助来修复我在这个程序中使用的一个功能,但现在我失去了逻辑。

我在这个程序中有三个目的和两个功能。第一个目的是打印用户向后输入的句子。第二个目的是检查句子中是否有任何单词与另一个单词是字谜。第三个目的是检查任何一个单词是否是回文。

我成功地完成了第一个目的。我可以倒着打印句子。但是现在我不确定我应该如何实现我的函数来检查任何单词是否是字谜或回文。

这是代码;

/*
 * Ch8pp14.c
 *
 *  Created on: Oct 12, 2013
 *      Author: RivalDog
 *      Purpose: Reverse a sentence, check for anagrams and palindromes
 */

#include <stdio.h>
#include <ctype.h> //Included ctype for tolower / toupper functions
#define bool int
#define true 1
#define false 0

//Write boolean function that will check if a word is an anagram
bool check_anagram(char a[], char b[])

   int first[26] = 0, second[26] = 0, c = 0;
// Convert arrays into all lower case letters
   while(a[c])
   
       a[c] = (tolower(a[c]));
       c++;
   

   c = 0;

   while(b[c])
      
       b[c] = (tolower(b[c]));
       c++;
      

      c = 0;

   while (a[c] != 0)
   
      first[a[c]-'a']++;
      c++;
   

   c = 0;

   while (b[c] != 0)
   
      second[b[c]-'a']++;
      c++;
   

   for (c = 0; c < 26; c++)
   
      if (first[c] != second[c])
         return false;
   

   return true;


//Write boolean function that will check if a word is a palindrome
bool palindrome(char a[])

    int c=0, j, k;
    //Convert array into all lower case letters
    while (a[c])
    
        a[c] = (tolower(a[c]));
        c++;
    

    c = 0;
    j = 0;
    k = strlen(a) - 1;
    while (j < k)
    
        if(a[j++] != a[k--])
            return false;
    

    return true;


int main(void)

    int i = 0, j = 0, k = 0;
    char a[80], terminator;
    //Prompt user to enter sentence, store it into an array
    printf("Enter a sentence: ");
    j = getchar();
    while (i < 80)
    
        a[i] = j;
        ++i;
        j = getchar();
        if (j == '!' || j == '.' || j == '?')
        
            terminator = j;
            break;
        
        else if(j == '\n')
        
            break;
        
    
    while(a[k])
    
        a[k] = (tolower(a[k]));
        k++;
    
    k = 0;
    while(k < i)
    
        printf("%c", a[k]);
        k++;
    
    printf("%c\n", terminator);
    //Search backwards through the loop for the start of the last word
    //print the word, and then repeat that process for the rest of the words
    for(j = i; j >= 0; j--)
    
        while(j > -1)
        
            if (j == 0)
            
                for(k=j;k<i;k++)
                    
                        printf("%c", a[k]);
                    
                printf("%c", terminator);
                    break;
            
            else if (a[j] != ' ')
                --j;
            else if (a[j] == ' ')
                
                    for(k=j+1;k<i;k++)
                        
                            printf("%c", a[k]);
                        
                    printf(" ");
                        break;
                
        
        i = j;
    
    //Check if the words are anagrams using previously written function
    for( i = 0; i < 80; i++)
    
        if (a[i] == ' ')
        

        
    

    //Check if the words are palindromes using previously written function

return 0;

我在想也许我可以通过检查元素是否为空格来再次在数组中搜索单词,如果是,则将从搜索开始的位置存储到新数组中的空格索引 1,重复该过程用于整个句子,然后在所有数组上调用我的函数。我看到的问题是我无法真正预测用户将在一个句子中输入多少个单词......那么我如何将我的代码设置为可以检查字谜/回文的位置?

谢谢大家!

~RivalDog

【问题讨论】:

可能更适合Code-Review site。 您的代码难以阅读。您应该使用过更高级的函数,例如 scanf() 或 fgets(),尤其是 strtok()。如果你使用 strtok(),倒着写一个句子是很容易的。我不会怪你,但如果你不知道 strtok(),现在你知道了。我强烈建议您使用它。有了这段代码,我怀疑有人会花时间理解它并帮助你。 阅读此answer。您将了解如何计算字符串中的单词数。 我认为,更改 check_anagram 的参数内容不是一个好主意...请不要编写有副作用的函数... @FilipeGonçalves Scanf 无法满足我的需求,而且我从未听说过或使用过 fgets() 或 strtok()。我不能使用它,因为我不知道它的作用。就个人而言,我觉得我的代码一点也不难读,而且我是新手。我有很多 cmets 解释了我需要帮助的代码部分发生了什么。 【参考方案1】:

如果您首先优化代码并通过添加 cmets 使其可读性会更好。然后您可以将问题分成更小的部分,例如 1.如何统计字符串中的单词? 2.如何判断两个单词是否为字谜? 3.如何判断一个单词是否为回文? 您可以通过谷歌搜索轻松获得这些较小的程序。那么你的工作就是整合这些答案。希望这会有所帮助。

【讨论】:

我已经知道如何检查字谜和回文。代码中有 cmets 对此进行了解释。因此,根据您的评论,我剩下要做的就是计算字符串中的单词数,但这是不正确的。还有更多的事情要做。一旦我计算了字符串中的单词数,如何通过我的 anagram 函数发送所有可能的单词对,以及如何通过我的回文函数发送每个单词? 然后您可以对单词使用某种散列,其中每个单词计算为某个唯一的散列值并将这些值存储在某个数组中。然后,如果您遇到一个单词,那么您需要计算该单词的哈希值并在数组中搜索以进行字谜。例如。单词'abcd'哈希可以计算为2 * 3 * 5 * 7,前四个素数的乘法。我的意思是你可以为每个字符分配一个素数。你需要找出前 26 个素数。现在,'abcd' 的任何组合总是将乘积作为 3*5*7*11。或者你可以自己想一些更好的哈希函数。【参考方案2】:

要检查字谜,无需计算单词的数量并逐一比较它们或您想什么。 看看这段代码。在此代码中,函数read_word() 正在使用包含 26 个元素的 int 数组读取单词/短语输入,以跟踪每个字母被看到的次数,而不是存储字母本身。另一个函数equal_array() 是检查数组ab(在main 中)是否相等(字谜)并返回一个布尔值作为结果。

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

void read_word(int counts[26]);
bool equal_array(int counts1[26],int counts2[26]);

int main()

    int a[26] = 0, b[26] = 0;

    printf("Enter first word/phrase: ");
    read_word(a);
    printf("Enter second word/phrase: ");
    read_word(b);

    bool flag = equal_array(a,b);
    printf("The words/phrase are ");
    if(flag)
        printf("anagrams");
    else
        printf("not anagrams"); 

    return 0;


void read_word(int counts[26])

    int ch;
    while((ch = getchar()) != '\n')
    if(ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')
        counts[toupper(ch) - 'A']++;


bool equal_array(int counts1[26],int counts2[26])

    int i = 0;
    while(i < 26)
    
        if(counts1[i] == counts2[i])
            i++;
        else
            break;  
    

    return i == 26 ? true : false;  

【讨论】:

以上是关于如何实现我的字谜和回文函数来检查用户输入的单词?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查两个字符串是不是是字谜?

给定单词的算法返回从它中删除所需的最小字母数量以成为回文的字谜

如何优化我的字谜搜索功能?

如何检查两个单词是不是是字谜

检查字符串是不是是字谜

查找字典单词的字谜