标题:有没有更简单发方法,求高手指教
只看楼主
qq471402415
Rank: 2
等 级:论坛游民
帖 子:88
专家分:45
注 册:2013-12-3
结帖率:82.35%
已结贴  问题点数:30 回复次数:15 
有没有更简单发方法,求高手指教
在当前目录中存在文件名为"case1.txt“的文本文件,
 其内容为一篇英文文章(以EOF作为结束标志)。现要求读取该文本文件内容,统计文章中每个单词出现的次数,
 并输出出现次数最多的前5个单词及其出现次数(按出现次数由多到少的顺序输出,次数相同时按字典顺序输出,
 不足5个单词时,按序输出全部单词)。程序中注意如下细节:
 (1)    空格、标点符号与回车符起到分隔单词的作用。
 (2)    文章一行的末尾可能有连字符,出现连字符时,该行最末的字符串与下行最先出现的字符串构一个单词;
 (3)    名词缩写算一个单词;
 (4)    数字不算单词;
 (5)    单词不区分大小写;
 (6)    输出时单词全使用小写;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
求高手化简程序!
#include "stdio.h"
#include "math.h"
#include "string.h"
#include "stdlib.h"
struct record_word
{
    char c[30];
    int n;
} word[10000];
int main()
{
    FILE *fp;
    char b[30],ch;
    int j=0,k=0,t=0,h=0,i=0,m=1,p=0;
    if((fp=fopen("case1.in","r"))==NULL)
    {
        printf("File open error!\n");
        exit(0);
    }
    while((ch=fgetc(fp))!=EOF)
    {
        if(p&&ch=='\n')
        {
            p=0;
            continue;
        }
        else if(p&&ch!='\n')
        {
            p=0;
            i=h=m=0;
            for(j=0; j<k; j++)
            {
                if(strcmp(b,word[j].c)==0)
                {
                    m=1;
                    break;
                }
            }
            if(m) word[j].n++;
            else
            {
                word[k].n=1;
                strcpy(word[k].c,b);
                k++;
            }
        }
        if(ch>='A'&&ch<='Z')ch=ch+32;
        if(ch>='a'&&ch<='z')
        {
            b[i]=ch;
            i++;
            h=1;
            continue;
        }
        else if(!(ch>='a'&&ch<='z'))
        {
            h=0;
        }
        if(h==0)
        {
            b[i]='\0';
            if(ch=='-')
            {
                p=1;
                continue;
            }
            else
            {
                i=h=m=0;
                for(j=0; j<k; j++)
                    if(strcmp(b,word[j].c)==0)
                    {
                        m=1;
                        break;
                    }
                if(m) word[j].n++;
                else
                {
                    word[k].n=1;
                    strcpy(word[k].c,b);
                    k++;
                }
            }
        }
    }
    for(i=0; i<k&&i<5; i++)
    {
        t=0;
        for(j=1; j<k; j++)
        {
            if(strcmp(word[j].c,"\0")!=0)
            {
                if(word[j].n>word[t].n)  t=j;
                else if(word[j].n==word[t].n)
                    if(strcmp(word[j].c,word[t].c)<0)
                        t=j;
            }
        }
        printf("%s %d\n",word[t].c,word[t].n);
        word[t].n=0;
    }
    return 0;
}
搜索更多相关主题的帖子: 标点符号 文本文件 英文文章 字符串 
2014-03-03 18:44
wp231957
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:神界
等 级:版主
威 望:422
帖 子:13681
专家分:53296
注 册:2012-10-18
得分:0 
以前有人发过相同的题目

DO IT YOURSELF !
2014-03-03 20:33
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
得分:25 
我写个来讨论一下. 前面部分用ctype.h文件优化了一下, 后面的输出部分用的是你的,
用word, lastc两个变量做标记, word标记输入的字符是否属于一个单词, lastc标记当字符不是字母时, 是否为一个单词结束.  
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define IN  1
#define OUT 0

struct record_word
{
    char c[30];
    int n;
} w[10000];

int main()
{
    FILE *fp;
    int ch;
    int i, j, n = 0, t;
    int word = OUT;         // OUT表示现在读取的字符不属于一个单词, IN表示正在读取一个单词
    char s[30], lastc = ' ';  // lastc保存读取的前一个字符, 当现在的字符不是字母, 前一个是字母, 表示一个单词结束

    fp = fopen("casel.txt", "r");
    if (fp == NULL)
        exit(1);

    while ((ch = fgetc(fp)) != EOF) {
        if (isalpha(ch)) {
            ch = tolower(ch);               
            if (word == OUT) {   // 当读取一个字母时, 判断是一个新单词的开始, 还是旧单词的一部分
                i = 0;
                word = IN;
            }
            s[i++] = ch;
        }
        else if (ch == '-'){
            fgetc(fp);                // 读取连字符后面的回车符, 如果后面没有回车符的, 可以删除这句
            continue;
        }
        else if (isalpha(lastc)) {   // 如果读取的不是字母, 而前一个字符是字母, 表示一个单词结束, 则处理这个单词, 否则,不操作
            word = OUT;
            s[i] = '\0';
            for (j = 0; j <= n; j++)
                if (strcmp(s, w[j].c) == 0) {
                    w[j].n++;
                    break;
                }
            if (j > n) {
                n = j;
                w[j].n++;
                strcpy(w[j].c, s);
            }
        }
        lastc = ch;
    }

    for(i=0; i<n&&i<5; i++)
    {
        t=0;
        for(j=1; j<=n; j++)
        {
            if(strcmp(w[j].c,"\0")!=0)
            {
                if(w[j].n>w[t].n)  t=j;
                else if(w[j].n==w[t].n)
                    if(strcmp(w[j].c,w[t].c)<0)
                        t=j;
            }
        }
        printf("%s %d\n",w[t].c,w[t].n);
        w[t].n=0;
    }

    fclose(fp);
    return 0;
}

 
2014-03-04 14:47
qq471402415
Rank: 2
等 级:论坛游民
帖 子:88
专家分:45
注 册:2013-12-3
得分:0 
回复上一楼,我测试一下;你的结果是~~
标准输入数据:
I am a student. -1 = 1 - 2. q=a-m. z = i - w. My school is SCAU. It is a beau-
tiful university. t-t-t-t, 123 123. I like it.


标准输出答案:
   1|t 4
   2|a 3
   3|i 3
   4|is 2
   5|it 2


你的错误输出结果:
   1|a 3
   2|i 3
   3|is 2
   4|it 2
   5|am 1
2014-03-05 22:45
qq471402415
Rank: 2
等 级:论坛游民
帖 子:88
专家分:45
注 册:2013-12-3
得分:0 
你的连字符那没处理好 1

[ 本帖最后由 qq471402415 于 2014-3-5 22:49 编辑 ]
2014-03-05 22:45
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
得分:0 
程序代码:
else if (ch == '-'){
            fgetc(fp);                // 读取连字符后面的回车符, 如果后面没有回车符的, 可以删除这句
            continue;
        }
改成:
else if (ch == '\n' && lastc == '-')
            continue;
      

2014-03-06 08:12
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
得分:5 
以下是引用pangshch在2014-3-6 08:12:57的发言:

else if (ch == '-'){
            fgetc(fp);                // 读取连字符后面的回车符, 如果后面没有回车符的, 可以删除这句
            continue;
        }
改成:else if (ch == '\n' && lastc == '-')
            continue;
      
这样改下挺好
2014-03-06 08:37
qq471402415
Rank: 2
等 级:论坛游民
帖 子:88
专家分:45
注 册:2013-12-3
得分:0 
还是有问题~~~看
测试数据用例 No.2

标准输入数据:
I am a student. My school is SCAU. It is a beau-
tiful university. I like it.
I am a student. My school is SCAU. It is a i-
s university. I like it.
1 2 3 4 5 6 7 8 9
12 12 12 12
II I


标准输出答案:
   1|i 5
   2|is 5
   3|a 4
   4|it 4
   5|am 2


你的错误输出结果:
   1|i 6
   2|a 4
   3|is 4
   4|it 4
   5|am 2
2014-03-06 11:01
qq471402415
Rank: 2
等 级:论坛游民
帖 子:88
专家分:45
注 册:2013-12-3
得分:0 
还是有问题~~~看
测试数据用例 No.2

标准输入数据:
I am a student. My school is SCAU. It is a beau-
tiful university. I like it.
I am a student. My school is SCAU. It is a i-
s university. I like it.
1 2 3 4 5 6 7 8 9
12 12 12 12
II I


标准输出答案:
   1|i 5
   2|is 5
   3|a 4
   4|it 4
   5|am 2


你的错误输出结果:
   1|i 6
   2|a 4
   3|is 4
   4|it 4
   5|am 2
2014-03-06 11:01
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
得分:0 
以下是引用qq471402415在2014-3-6 11:01:20的发言:

还是有问题~~~看
测试数据用例 No.2
 
标准输入数据:
I am a student. My school is SCAU. It is a beau-
tiful university. I like it.
I am a student. My school is SCAU. It is a i-
s university. I like it.
1 2 3 4 5 6 7 8 9
12 12 12 12
II I
 
 
标准输出答案:
   1|i 5
   2|is 5
   3|a 4
   4|it 4
   5|am 2
 
 
你的错误输出结果:
   1|i 6
   2|a 4
   3|is 4
   4|it 4
   5|am 2
我的运行没问题.
你是不是else if (ch == '\n' && lastc == '-') {
            fgetc(fp);   // 这句没删除?
            continue;
}
2014-03-06 11:13



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-427954-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.215056 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved