【问题标题】:Anagram project字谜项目
【发布时间】:2015-02-01 22:44:33
【问题描述】:

我在尝试使用“isZero”函数来检测单词是否是字谜时遇到了麻烦。在 main() 中询问“isZero”是否等于 1,它只会给我“字谜”。如果我将它设置为 0,它只会给我“不是字谜”。对我来说,它没有计算任何东西,它只是打印出此刻任何正确的陈述。不知道如何解决这个问题,可以使用一些指导。

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

 #define MAX 26

void intialize(char a[], char b[], int c[]);
void setLetters(char newCount[], int newNumber[]);
void checkLetters(char b[], int newNumber[]);
int isZero(int c[]);
void getstring(char a[]);
void getString(char b[]);

int main(void)
{
    char a[MAX], b[MAX];
    int c[MAX];

    intialize( a, b, c);
    getstring(a);
    getString(b);
    setLetters(a, c);
    checkLetters(b, c);

    if (isZero(c) == 1) {
        printf("anagram");
    } else
        printf("not anagram");
    return 0;
}

void intialize(char a[], char b[], int c[])
{
    int i;
    for(i = 0; i < MAX; ++i) {

        a[i] = '\0';
        b[i] = '\0';
        c[i] = 0;
    }
}
void setLetters(char newCount[], int newNumber[])
{
    int i, index = 0;
    for(i = 0; i < MAX; ++i) {
        if(isalpha(newCount[i])) {
            newCount[i] = tolower(newCount[i]);
            index = (int)(newCount[i] - 'a');
            newNumber[index] +=1;
        }
    }
}
void checkLetters(char b[], int newNumber[])
{
    int i, index;
    for(i = 0; i < MAX; ++i) {
        if(isalpha(newNumber[i])) {
            newNumber[i] = tolower(newNumber[i]);
            index = (int)(newNumber[i] - 'a');
            newNumber[index] -= 1;
        }
    }
}
int isZero(int c[])
{
    int i, j = 0;
    for(i = 0; i < MAX; ++i) {
        if(c[i] == 0)
            j = 1;
        else
            return 0;
    }
    return j;
}
void getstring(char a[])
{
    char line[MAX];

    printf("Enter a string: ");
    gets(line);
}
void getString(char b[])
{
    char line[MAX];

    printf("Enter a string: ");
    gets(line);
}

【问题讨论】:

  • 你知道你可以简单地声明char a[MAX] = {0};int c[MAX] = {0};而不是initializeb也是如此)。另外从不,从不,从不使用gets()!。由于不安全,它不再是 C 库的一部分。使用fgetsgetline 甚至scanf

标签: c function anagram


【解决方案1】:

对于 C,您必须放慢速度并了解每行的每个部分的作用。 C 的任何部分足够接近正确。话虽如此,你对如何解决这个问题有了一个整体的想法。但是,很明显您刚刚开始使用 C 语言(鉴于其他答案和 cmets)。

在开始编写函数之前,请确定函数需要做什么。然后尝试确定如何最好地处理该任务。如果您需要一个函数来获取字符串输入,那么请编写一个函数来执行此操作。如果您发现自己必须编写一个函数来填充每个字符串stop,那么您就违背了该函数的目的。为a[] 编写一个函数来做同样的事情,而为b[] 编写另一个相同的函数 是没有意义的。您不需要一个函数来遍历所有数组,将您新声明的数组设置为zero/NULL,这就是数组初始化语法的用途。

在您希望函数正常工作之前,请花时间学习如何将值传递给函数(如果需要返回,则从函数中获取值)。当您将数组传递给函数时,会发生指针衰减。这意味着数组a[] 在传递给函数时衰减为*a。您可以通过声明您的函数接受*a 作为参数来利用这一点。虽然这对于简单的1-D 数组来说并不是惊天动地的,但衰减在2-D 及以上的数组中变得更加重要。

除了弄清楚哪些代码作为函数有意义之外,您还需要准确地了解 C 中的逻辑,就像了解其语法一样。如果您不确定某行的任何部分,请查看它,查看您正在使用的函数的手册页,或查阅编译器 (Gnu/MS) 的语言参考等,以确保您知道正是您的代码所做的。从长远来看,它将为您节省时间。让新 C 程序员绊倒的第一件事是尝试略读手册略读书籍然后开始编写代码。学习 C 的关键是放慢速度

永远不要,永远不要,永远不要使用gets()。如果您正在上课并且老师使用它给您分配作业,请前往管理部门并要求退款。 gets() 不再是标准 C 库的一部分,因为它很容易被破坏和利用。使用fgetsgetlinescanf(如果您选择使用scanf格式字符串,请阅读有关正确使用的整个部分)。这是一个很好的功能,但它有很多很多的陷阱,只是等待部分了解它的使用的人。

话虽如此,您已经掌握了一种处理字谜的整体逻辑。下面我在整理您的代码时提供了上述要点的示例。花点时间通读一遍,了解我为什么做出这些改变。此外,我添加了一个快速length 检查输入的单词。如果它们的长度不同,则无需进一步。如果您有任何问题,请告诉我。这里有很多好人很乐意提供帮助。

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

#define MAX 26

void setLetters(char *newCount, int *newNumber);
void checkLetters(char *newCount, int *newNumber);
int isZero (int *c);
void getstring (char *a);

int main (void)
{
    char a[MAX] = {0};  /* initialize all to zero/NULL */
    char b[MAX] = {0};
    int  c[MAX] = {0};

    getstring(a);
    getstring(b);
    printf ("\n You entered:\n\n  a: %s\n  b: %s\n\n", a, b);

    /* test lengths - if differ, not anagram */
    if (strlen(a) != strlen(b)) {
        printf (" Lenghts differ, cannot be an anagram.\n\n");
        return 1;
    }

    setLetters (a, c);      /* set key array  (c)   */
    checkLetters (b, c);    /* check key array (c)  */

    if (isZero(c))
        printf(" The words form an anagram.\n\n");
    else
        printf(" The words are not and anagram.\n\n");

    return 0;
}

void setLetters (char *newCount, int *newNumber)
{
    int i = 0;
    int index = 0;

    for (i = 0; i < MAX; ++i) {
        if (isalpha (newCount[i])) {
            newCount[i] = tolower (newCount[i]);
            index = (int)(newCount[i] - 'a');
            newNumber[index] +=1;
        }
    }
}

void checkLetters(char *newCount, int *newNumber)
{
    int i = 0;
    int index = 0;

    for (i = 0; i < MAX; ++i) {
        if (isalpha (newCount[i])) {
            newCount[i] = tolower (newCount[i]);
            index = (int)(newCount[i] - 'a');
            newNumber[index] -= 1;
        }
    }
}

int isZero (int *c)
{
    int i = 0;
    for (i = 0; i < MAX; ++i)
        if (c[i] == 1)
            return 0;

    return 1;
}

void getstring (char *a)
{
    printf ("\n Enter a string: ");
    scanf  ("%[^\n]%*c", a);
}

输出:

$ ./bin/anaproj

 Enter a string: yekcim

 Enter a string: mickey

 You entered:

  a: yekcim
  b: mickey

 The words form an anagram.

$ ./bin/anaproj

 Enter a string: yekcim

 Enter a string: mickez

 You entered:

  a: yekcim
  b: mickez

 The words are not and anagram.

【讨论】:

  • 非常感谢。关于您的代码,我想问几个问题,您实现或更改的某些事情我不明白。现在已经很晚了,该睡觉了。但我一定会回到这个讨论。再次感谢。
  • 当然。发表评论,如果我在,我很乐意与您打开一个聊天窗口。
【解决方案2】:
void getstring(char a[]);

这个 API 没有做你想做的事。 这有一个局部变量行,你正在读取一个字符串,main() 中的 char 数组,即a 永远不会被任何东西填满。

您继续使用 char 数组 a,认为通过调用 getstring() 将值填充到其中并没有发生。您需要先解决这个问题,然后再研究 anagram 的算法。 有一种称为传递引用的方法可能会对您有所帮助。

【讨论】:

    猜你喜欢
    • 2012-09-20
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 2016-11-10
    • 2011-11-03
    相关资源
    最近更新 更多