在c程序中输出频率的问题,应该将txt文件与关键字进行比较并输出频率

xn1cxnb4  于 2023-11-16  发布在  其他
关注(0)|答案(2)|浏览(126)

希望大家都好!我有点困在我的编程作业,c代码的目的是比较一个txt文件(名称作为用户输入)另一个关键字txt文件.然后记录每个单词的频率并按降序打印它们.这应该看起来像这样:

euery 8
common 8
gaue 7
thankes 5
vnkle 4
growes 3
wag 3
seal 3
day 3
soft 3

字符串
代码如下所示:

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

#define MAX_FILENAME_LENGTH 256
#define MAX_TEXT_LENGTH 100000
#define MAX_KEYWORDS 100

// Structure to store keyword frequencies
typedef struct KeywordFrequency {
    char keyword[50];
    int frequency;
} KeywordFrequency;

// Compare function for sorting keyword frequencies
int compareKeywords(const void *a, const void *b) {
    return ((KeywordFrequency *)b)->frequency - ((KeywordFrequency *)a)->frequency;
}

int main() {
    char filename[MAX_FILENAME_LENGTH];
    char text[MAX_TEXT_LENGTH];
    KeywordFrequency keywords[MAX_KEYWORDS];
    int totalKeywords = 0;

    // Ask the user for the name of the text file
    printf("Enter the name of the text file: ");
    scanf("%s", filename);

    // Open and read the text file
    FILE *textFile = fopen(filename, "r");
    if (textFile == NULL) {
        printf("Error opening %s\n", filename);
        return 1;
    }

    // Read the content of the text file
    fread(text, 1, sizeof(text), textFile);
    fclose(textFile);

    // Open and read the keyword file
    FILE *keywordFile = fopen("keyword.txt", "r");
    if (keywordFile == NULL) {
        printf("Error opening keyword.txt\n");
        return 1;
    }

    // Initialize keyword frequencies
    while (fscanf(keywordFile, "%s", keywords[totalKeywords].keyword) != EOF) {
        keywords[totalKeywords].frequency = 0;
        totalKeywords++;
    }
    fclose(keywordFile);

    // Tokenize and compare the text with keywords
    char *token = strtok(text, " ");
    while (token != NULL) {
        for (int i = 0; i < totalKeywords; i++) {
            if (strcmp(token, keywords[i].keyword) == 0) {
                keywords[i].frequency++;
            }
        }
        token = strtok(NULL, " ");
    }

    // Sort keyword frequencies in descending order
    qsort(keywords, totalKeywords, sizeof(KeywordFrequency), compareKeywords);

    // Print the results in a table format
    printf("Keyword\tFrequency\n");
    for (int i = 0; i < totalKeywords; i++) {
        printf("%s\t%d\n", keywords[i].keyword, keywords[i].frequency);
    }

    return 0;
}


enter image description here
任何帮助都将不胜感激

6jjcrrmo

6jjcrrmo1#

正如@someprogrammerdude在他的回答中指出的那样,使用"%s"只会读取一个空格分隔的单词。为了将整行文本读入足够大的缓冲区,fgets()是首选函数。(事实上,这是阅读文本或用户输入的首选方式)。从fgets()sscanf()填充的缓冲区中(分离)您需要的值。与直接使用fscanf()相比,这提供了几个好处。它简化了读取和解析,并允许对每个步骤进行单独验证。
继续我的评论,不要使用 Magic-Numbers50在你的结构定义中是一个 Magic-Number。你用#define声明常量做得很好,只需要为keyword成员数组定义一个常量。你用MAX_TEXT_LENGTH也做得很好 * 不忽略缓冲区大小 *,但是你可以为手头的文件定制更窄一点。一般来说,行不超过1 K左右。100 K当然涵盖了这一点,但是在嵌入式或内存有限的系统上,这对于读缓冲区来说可能有点多。对于这里的行,100 bytes就可以了。(这仍然是最长行的10倍)所以下面的代码就可以了:

#define MAX_FILENAME_LENGTH 256
// #define MAX_TEXT_LENGTH 100000
#define MAX_KEYWORDS 100
#define MAX_LINE MAX_KEYWORDS
#define MAX_CHARS 50

字符串
注意:limits.h提供了PATH_MAX定义,给出了系统的最大路径名长度,这是一种方便的方法来调整filename数组的大小)
现在,为了消除 Magic-Number,只需将KeywordFrequency结构体定义为:

/* Structure to store keyword frequencies */
typedef struct KeywordFrequency {
  char keyword[MAX_CHARS];
  int frequency;
} KeywordFrequency;


虽然你的变量声明是好的,但初始化所有变量和数组是一个好习惯(特别是在学习C语言时),当变量的值不确定时,防止无意中访问具有自动存储持续时间的变量(a/k/a Undefined Behavor)如果可能的话,通过在作用域的开始定义变量,可以确保代码可移植到所有C语言标准。一个轻微的重新排列可能是:

char  filename[MAX_FILENAME_LENGTH] = "", /* initialize empty-string */
        text[MAX_LINE] = "";
  int totalKeywords = 0;
  FILE *textFile = NULL;
  /* initialize array of struct all zero */
  KeywordFrequency keywords[MAX_KEYWORDS] = {{.keyword = ""}};


所有用户输入都应该使用fgets(),以确保一次读取一整行(包括用户按Enter键生成的'\n')。这样,在你的输入流中是否还有额外的字符是毫无疑问的(例如stdin)unread --只是在等待下一次读取尝试时咬你。要删除fgets()读取并包含在fgets()填充的缓冲区中,简单地使用strcspn(),如下所示。您的输入可以视为:

/* prompt for name of the text file */
  fputs ("Enter the name of the text file: ", stdout);
  /* validate every input */
  if (!fgets (filename, MAX_FILENAME_LENGTH, stdin)) {
    /* how do you know this occurred? */
    puts ("user canceled input with manual EOF");
    return 0;
  }
  
  /* trim '\n' from end of filename overwriting with nul-character */
  filename[strcspn (filename, "\n")] = 0;


现在打开你的文件并输入你的 read-loop 阅读你的文件内容到你的struct KeywordFrequency数组中。注意:你总是想在你的 read-function 返回时设置你的 read-loop。在这里你可以这样做:

/* Open and read the text file */
  if (!(textFile = fopen(filename, "r"))) {
    perror ("textfile");
    return 1;
  }
  
  /* condition your read loop on your read function return */
  while (fgets (text, MAX_LINE, textFile)) {
    /* validate parse of information */
    if (sscanf (text, "%49s %d", keywords[totalKeywords].keyword,
                                 &keywords[totalKeywords].frequency) != 2) {
      /* handle invalid formatted line */
      fprintf (stderr, "error: bad format for index %d\n", totalKeywords);
      /* skip to next line in file */
      continue;
    }
    
    totalKeywords += 1;     /* increment index */
  }


(*注意:
剩下的就是用qsort()排序了。根据我的评论,你想重新排列你的compare()函数,这样它就可以返回条件表达式的结果而不是减法。为什么?你可以很容易地溢出减去两个大的负数。使用比较可以避免这种可能性,例如。

/* qsort compare function for sorting keyword frequencies
 * using (a < b) - (a > b) for descending sort to avoid potential overflow.
 * for ascending sort use: (a > b) - (a < b)
 */
int compareKeywords(const void *a, const void *b) {
  const KeywordFrequency  *x = a,
                          *y = b;
  
  return (x->frequency < y->frequency) - (x->frequency > y->frequency);
}
...
  /* Sort keyword frequencies in descending order */
  qsort (keywords, totalKeywords, sizeof *keywords, compareKeywords);

  /* Print the results in a table format */
  printf ("%-16s Frequency\n", "Keywords");
  for (int i = 0; i < totalKeywords; i++) {
    printf ("%-16s %d\n", keywords[i].keyword, keywords[i].frequency);
  }


你的基本代码表明你正在努力学习C的正确方法。这是学习C的唯一方法。否则,你会加倍学习时间来打破坏习惯,学习你应该在第一次学习的东西。保持良好的工作。完整的例子如下所示:

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

#define MAX_FILENAME_LENGTH 256
// #define MAX_TEXT_LENGTH 100000
#define MAX_KEYWORDS 100
#define MAX_LINE MAX_KEYWORDS
#define MAX_CHARS 50

/* Structure to store keyword frequencies */
typedef struct KeywordFrequency {
  char keyword[MAX_CHARS];
  int frequency;
} KeywordFrequency;

/* qsort compare function for sorting keyword frequencies
 * using (a < b) - (a > b) for descending sort to avoid potential overflow.
 * for ascending sort use: (a > b) - (a < b)
 */
int compareKeywords(const void *a, const void *b) {
  const KeywordFrequency  *x = a,
                          *y = b;
  
  return (x->frequency < y->frequency) - (x->frequency > y->frequency);
}

int main() {
    
  char  filename[MAX_FILENAME_LENGTH] = "", /* initialize empty-string */
        text[MAX_LINE] = "";
  int totalKeywords = 0;
  FILE *textFile = NULL;
  /* initialize array of struct all zero */
  KeywordFrequency keywords[MAX_KEYWORDS] = {{.keyword = ""}};

  /* prompt for name of the text file */
  fputs ("Enter the name of the text file: ", stdout);
  /* validate every input */
  if (!fgets (filename, MAX_FILENAME_LENGTH, stdin)) {
    /* how do you know this occurred? */
    puts ("user canceled input with manual EOF");
    return 0;
  }
  
  /* trim '\n' from end of filename overwriting with nul-character */
  filename[strcspn (filename, "\n")] = 0;
  
  /* Open and read the text file */
  if (!(textFile = fopen(filename, "r"))) {
    perror ("textfile");
    return 1;
  }
  
  /* condition your read loop on your read function return */
  while (fgets (text, MAX_LINE, textFile)) {
    /* validate parse of information */
    if (sscanf (text, "%49s %d", keywords[totalKeywords].keyword,
                                 &keywords[totalKeywords].frequency) != 2) {
      /* handle invalid formatted line */
      fprintf (stderr, "error: bad format for index %d\n", totalKeywords);
      /* skip to next line in file */
      continue;
    }
    
    totalKeywords += 1;     /* increment index */
  }
  
  /* Sort keyword frequencies in descending order */
  qsort (keywords, totalKeywords, sizeof *keywords, compareKeywords);

  /* Print the results in a table format */
  printf ("%-16s Frequency\n", "Keywords");
  for (int i = 0; i < totalKeywords; i++) {
    printf ("%-16s %d\n", keywords[i].keyword, keywords[i].frequency);
  }
}

示例使用/输出

编译上面的代码(在编译所有程序时使用 *Full Enhanced *),然后以您的数据文件作为输入运行程序,您将获得:

$ ./bin/wordfreq-read-sort
Enter the name of the text file: dat/wordfreq.txt
Keywords         Frequency
euery            8
common           8
gaue             7
thankes          5
vnkle            4
growes           3
wag              3
seal             3
day              3
soft             3


(**注意:**你也可以按频率排序,如果频率相等,只需要几行额外的代码)
把东西看一遍,如果有问题就告诉我。

**=

好的,所以你的问题中的文件是一个示例输出文件,而不是输入文件--明白了。
以下是所需更改的简短摘要:

  • 使用fscanf (fp, "%s", word)是一种很好的方式来阅读 * 一次一个单词 *(使用适当的 * 字段宽度 * 修饰符)。

  • 而不是分配100 K的结构,只是分配2到开始,然后realloc()当你填写你所分配的。与您的115页文本,每次需要realloc()时简单地将大小加倍只需要17个realloc()调用来容纳文件。(在大多数情况下,它是内存增长和需要重新分配的次数之间的一个很好的平衡)

  • 一旦你读了一个单词,你需要一个函数来检查它是否已经存在于你的单词集合中,如果存在,只需将频率增加1,如果没有,检查你的集合中是否有空间添加单词,如果没有realloc(),然后添加单词并将频率设置为1。

    • 留给你:*
  • "%s"不能区分"[The""The",所以你应该根据需要检查并删除标点符号。像"yours""yours,""yours.""yours:""yours;"(都在你的输入文件中)。一个简单的函数,从buf中去掉前导和尾随标点符号就可以了。

  • 你有几个很长的连字符的单词要处理,例如"Pastoricall-Comicall-Historicall-Pastorall""Tragicall-Comicall-Historicall-Pastorall"。没有明确的规则来处理连字符的单词。它们是完全有效的,在你的输入文档的上下文中更是如此。

  • 一个选项是保持最大单词长度,然后动态调整输出间距以容纳列表中最长的单词。您可以使用printf()字符串中的'*'来实现这一点,提供最大单词长度变量来指定关键字字段的 * 最小字段宽度 *。

有了这个前提,我就可以很容易地修改你的代码来做需要做的事情。(而不是修改,我只是重写了它,我不喜欢 camelCase 变量名,我尽量保持名称简短但具有描述性--因为我不喜欢键入:)
你可以做类似的事情:

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

#define MAXWORDCHAR 64

typedef struct {
  char word[MAXWORDCHAR];
  size_t freq;
} wordfreq;

/* qsort compare function for sorting keyword frequencies
 * using (a < b) - (a > b) for descending sort to avoid potential overflow.
 * for ascending sort use: (a > b) - (a < b)
 */
int cmpwordfreq (const void *a, const void *b) {
  const wordfreq  *x = a,
                  *y = b;
#ifdef ALPHASORTEQUAL
  /* sort alphabetically if frequencies are equal */
  if (x->freq == y->freq) {
    return (strcmp (x->word, y->word));
  }
#endif
  /* sort by frequency */
  return (x->freq < y->freq) - (x->freq > y->freq);
}

/* check if word exists in allocated wordfreq structs
 * returns index of word if it exits, -1 otherwise.
 */
int wordexists (const char *word, const wordfreq *wf, size_t n)
{
  /* validate both word and wf not NULL */
  if (!word || !wf) {
    return -1;    /* no word in struct */
  }
  
  /* loop over each struct comparing word stored with word */
  for (size_t i = 0; i < n; i++) {
    if (strcmp (word, wf[i].word) == 0) {
      return i;   /* return index if found */
    }
  }
  
  return -1;      /* no word in struct */
}

int main (int argc, char **argv) {
  
  char buf[MAXWORDCHAR];    /* buffer to hold each word in file */
  wordfreq *wf = NULL;     /* pointer to allocated collection of struct */
  size_t  allocated = 0,    /* no. of structs allocated */
          used = 0;         /* no. of structs used */
  /* use filename provided as 1st argument (stdin by default) */
  FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

  if (!fp) {  /* validate file open for reading */
    perror ("file open failed");
    return 1;
  }
  
  /* loop reading each word in file */
  while (fscanf (fp, "%63s", buf) == 1) {
    int index = wordexists (buf, wf, used);   /* check if word in struct */
    if (index >= 0) {             /* if word exists */
      wf[index].freq += 1;       /* increment freq for word */
      continue;
    }
    /* if all storage used, realloc more */
    if (used == allocated) {
      /* always realloc to a temporary pointer */
      void *tmp = realloc (wf, (allocated ? 2 * allocated : 2) * sizeof *wf);
      /* validate realloc return */
      if (!tmp) {                       /* if realloc failed */
        perror ("realloc-wf-failed");   /* output error */
        break;                          /* break read loop */
      }
      wf = tmp;                                   /* assign realloced block */
      allocated = allocated ? allocated * 2 : 2;  /* update no. allocated */
    }
    
    strcpy (wf[used].word, buf);        /* copy word to struct */
    wf[used++].freq = 1;               /* set freq to 1, increment used */
  }
  
  if (fp != stdin)   /* close file if not stdin */
    fclose (fp);
  
  qsort (wf, used, sizeof *wf, cmpwordfreq);
  
  /* Print the results in a table format */
  printf ("%-20s Frequency\n", "Keywords");
  for (size_t i = 0; i < used; i++) {
    printf ("%-20s %zu\n", wf[i].word, wf[i].freq);
  }
  
  free (wf);    /* don't forget to free what you allocated */
}

**注意:**我添加了ALPHASORTEQUAL的预处理器条件,以允许您以相等的频率对单词进行排序。预处理器条件只是允许您根据是否定义了代码来有条件地 * 包含 * 或 * 排除 * 代码。例如,什么都不做将排除按顺序排序的代码,但添加定义(无论是在代码中)还是在编译字符串中,例如-DALPHASORTEQUAL用于gcc/clang或/DALPHASORTEQUAL用于VS将 * 包含 * 代码。
启用全功能编译

我在最初的回答中提到了这一点,但没有给予示例。使用gcc,包含-Wall -Wextra -pedantic -Wshadow的编译字符串将启用接近所有警告(绝对涵盖了所有学习C代码的案例)。添加-Werror将警告视为错误(所以不能作弊)。不要接受代码,直到它编译没有警告。对于VS编译器(cl.exe)使用/W3就可以了。
当出现警告时,阅读并理解每个警告-然后修复它。警告将识别任何问题,以及它们发生的确切行。你可以通过简单地倾听编译器告诉你的东西来学习很多东西。在过去的20年里,他们已经非常非常擅长提供描述性警告。
我在这段代码中使用的编译字符串示例:

$ gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -o bin/word-freq word-freq.c


如果单词频率相等,要启用字母排序,只需定义ALPHASORTEQUAL,例如。

$ gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -DALPHASORTEQUAL -o bin/word-freq word-freq.c


(**注意:**我把数据文件放在当前目录下的dat/目录下,把可执行文件放在当前目录下的bin/目录下,以保持当前目录下的C源代码文件与其他东西的直接整洁。这就是为什么你在编译字符串中看到-o bin/...,在下面看到dat/...的文件名读取)

示例使用/输出
**注意:**如果您尝试将google-docs中的文件保存为 Plain Text,则会将其保存为DOS格式的BOM(字节顺序标记)。如果在Linux上,请运行dos2unix filename.txt将其转换为Unix行尾并删除BOM。

对于dat/word-freq-main.txt中的转换文件,您只需将其作为第一个命令行参数传递给程序,例如。

$ ./bin/word-freq dat/word-freq-main.txt
Keywords             Frequency
the                  860
and                  605
to                   574
of                   571
I                    520
a                    435
my                   433
you                  402
Ham.                 337
in                   336
it                   285
is                   273
his                  264
And                  255
not                  254
your                 233
that                 227
with                 207
this                 195
me                   163
for                  159
be                   158
haue                 154
he                   149
but                  145
as                   134
The                  132
will                 122
our                  118
him                  116
That                 114
To                   109
so                   109
what                 108
are                  107
But                  103
shall                103
on                   100
King.                96
we                   96
Hor.                 95
by                   88
thou                 87
Lord                 83
no                   83
thy                  83
What                 82
from                 79
all                  78
her                  78
Lord,                73
or                   73
more                 70
Enter                69
at                   69
good                 69
was                  69
For                  68
Oh                   68
they                 68
do                   67
My                   66
like                 66
most                 65
It                   64
if                   63
A                    62
As                   62
Qu.                  62
Laer.                60
then                 59
Ile                  58
know                 58
Ophe.                56
let                  55
How                  54
may                  54
would                54
must                 52
should               50
Pol.                 49
hath                 49
an                   48
If                   47
You                  47
there                47
am                   46
did                  46
now                  46
their                46
come                 45
such                 45
them                 45
So                   44
very                 44
Rosin.               43
This                 43
make                 43
selfe                43
With                 42
some                 42
Hamlet               41
In                   41
Why                  41
much                 41
He                   40
King                 40
Let                  39
thee                 39
Polon.               38
giue                 38
had                  37
speake               37
tell                 37
too                  37
vpon                 37
vs                   37
'tis                 36
doe                  36
thinke               36
out                  35
Of                   34
mine                 34
one                  34
well                 34
Lord?                33
Then                 33
she                  33
these                33
which                33
see                  32
Mar.                 31
No                   31
O                    31
how                  31
it,                  31
We                   30
can                  30
say                  30
where                30
Clo.                 29
Or                   29
loue                 29
man                  29
you,                 29
King,                28
heere                28
him,                 28
owne                 28
go                   27
when                 27
'Tis                 26
Father               26
Hamlet,              26
cannot               26
could                26
might                26
time                 26
yet                  26
&                    25
th'                  25
When                 24
heare                24
made                 24
thus                 24
vp                   24
were                 24
Is                   23
Sir,                 23
doth                 23
Come                 22
Exeunt.              22
Good                 22
I,                   22
Now                  22
call                 22
into                 22
me,                  22
take                 22
Hamlet.              21
Where                21
Who                  21
hast                 21
put                  21
Giue                 20
Guild.               20
Which                20
Your                 20
hold                 20
set                  20
His                  19
great                19
him.                 19
i'th'                19
leaue                19
two                  19
whose                19
Do                   18
Exit                 18
Osr.                 18
They                 18
both                 18
comes                18
nor                  18
not,                 18
poore                18
pray                 18
sweet                18
thing                18
those                18
Fathers              17
Haue                 17
Heauen               17
Horatio,             17
Mother               17
Queene               17
Will                 17
against              17
any                  17
dead                 17
neuer                17
shew                 17
vs,                  17
Be                   16
come,                16
deere                16
does                 16
though               16
By                   15
God                  15
Laertes,             15
Nay,                 15
againe               15
death,               15
head                 15
looke                15
meanes               15
old                  15
so,                  15
you:                 15
Kin.                 14
No,                  14
Noble                14
Nor                  14
Not                  14
Thou                 14
about                14
bee                  14
hee                  14
keepe                14
many                 14
matter               14
me.                  14
nothing              14
seene                14
selfe,               14
this?                14
world                14
Enter.               13
Looke                13
Lord.                13
Players              13
Reynol.              13
There                13
There's              13
Vpon                 13
beleeue              13
euen                 13
faire                13
finde                13
goe                  13
ha's                 13
it.                  13
liue                 13
makes                13
night                13
off                  13
same                 13
sent                 13
who                  13
you?                 13
At                   12
Horatio              12
Laertes              12
Most                 12
Mother,              12
Other.               12
Our                  12
Queene,              12
Sir                  12
Would                12
beare                12
better               12
betweene             12
farre                12
hand                 12
part                 12
saw                  12
this,                12
true                 12
words                12
Come,                11
Father,              11
Heauen,              11
Ophelia,             11
beene                11
day                  11
death                11
downe                11
eare                 11
ere                  11
euer                 11
feare                11
first                11
life                 11
life,                11
little               11
long                 11
once                 11
other                11
play                 11
vse                  11
well,                11
why                  11
Are                  10
Barn.                10
Denmarke             10
Did                  10
England              10
Ghost.               10
Guil.                10
Nay                  10
Soule                10
Take                 10
Till                 10
Yet                  10
be,                  10
before               10
done                 10
downe,               10
end                  10
fit                  10
foule                10
him:                 10
is't                 10
is,                  10
me?                  10
now,                 10
o're                 10
sir,                 10
stand                10
then,                10
thoughts             10
<snip -- many more>

内存使用/错误检查

在你写的任何动态分配内存的代码中,你有两个关于任何内存块的责任:(1)总是为内存块保留一个指向起始地址的指针,(2)当它不再需要时,它可以被释放。
必须使用内存错误检查程序来确保您不会尝试访问内存或写入超出/超出已分配块的范围,尝试读取或基于未初始化的值进行条件跳转,最后确认您已释放所有已分配的内存。
对于Linux,valgrind是正常的选择。每个平台都有类似的内存检查器。它们都很容易使用,只需通过它运行您的程序。

$ valgrind ./bin/word-freq dat/word-freq-main.txt
<snip output>
yours                1
yours,               1
yours.               1
yours:               1
yours;               1
youth:               1
==14914==
==14914== HEAP SUMMARY:
==14914==     in use at exit: 0 bytes in 0 blocks
==14914==   total heap usage: 17 allocs, 17 frees, 1,303,920 bytes allocated
==14914==
==14914== All heap blocks were freed -- no leaks are possible
==14914==
==14914== For lists of detected and suppressed errors, rerun with: -s
==14914== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


始终确认您已释放了所有已分配的内存,并且没有内存错误。
如果你还有问题就告诉我。

sq1bmfud

sq1bmfud2#

两件事:
第一个是scanf``%s读的是 * 空格分隔的**单词 *。所以没有什么需要标记的。你甚至从来没有读过任何你试图标记的东西到text中;
第二件事是你把输入文件中的每一个单词都读到一个单独的“keyword”元素中,这不是你应该做的。如果输入文件中有超过100个单词,那么就会超出数组的界限。
相反,你应该读入另一个变量并搜索当前的关键字,看看它是否在数组中,如果是,则增加频率,否则添加它。

相关问题