Chinaunix首页 | 论坛 | 博客
  • 博客访问: 501776
  • 博文数量: 174
  • 博客积分: 8001
  • 博客等级: 中将
  • 技术积分: 1840
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-04 19:30
文章分类

全部博文(174)

文章存档

2011年(1)

2010年(24)

2009年(149)

我的朋友

分类: C/C++

2009-03-10 16:29:18

问题:从标准输入中读入N(1行以换行符结束且长度不超过2048的字符串,并在输入结束后输出其中最长10行的输入序号、长度和内容。当有多行长度相等的最长行时,输出最先输入的行的信息。分别使用不同的方法实现这一程序,比较各种方法的运行效率。

对于这个问题,我想要落脚在数据结构上。很明显,是有序的结构,而且要支持任一位置的插入和删除操作,适合这种操作的就是二叉树了。但是我不想返回以前在C语言下写的那些简易的数据结构,虽然它们可以工作,但是既然有STL作为C++标准的存在,毫无疑问要熟悉使用——它们不是C++的附庸,不是可有可无的东西!所以我努力开始用STL写程序。不过很明显的看到作为一个C程序员的残留,printf!

但是STL并没有二叉树这种数据结构,而是以红黑树作为内部存储结构提供了set和map。当然从数学角度来说,这个问题是key到value的一一映射。使用map来解决这个问题是再适合不过了。

这次没有先写好伪代码,所以实现上会有一些多余的东西。试着对于简单的程序,在脑中酝酿成熟再写,我想是必要的——写伪代码也是挺麻烦的一件事情?如果不是开发算法的情况下,还是可以避免这样做的必要。

//this file is to demo the use of map STL

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <map>

#define MAXLEN 2064

typedef struct
{
    int number;
    char *content;
}line_infoT;

//to care the << and >>, when use template, keep a space

typedef std::map< int, line_infoT *, std::less< int > > micp;

int main()
{
    int min_len=0;//the mininum length of members

    int micp_size=0;//the size of micp

    bool test_10=true;//when the micp gets 10 members, stop test micp_size

    FILE *data;
    char *line, *content, *temp_line;
    int line_len=0, number=0;
    micp line_micp;
    line_infoT *line_info;//to store the infomation for line


    line=(char *)malloc(sizeof(char)*MAXLEN);
    temp_line=line;
    if(line==NULL)
    {
        exit(1);
    }
    data=fopen("data", "r");
    if(data==NULL)
    {
        exit(1);
    }
    while(!feof(data))
    {
        line=temp_line;//take line back to the original head

        fgets(line, MAXLEN, data);
        while(isspace(*line++));//to delete the space in the begin of line

        line--;
        line_len=strlen(line);
            if(test_10 || line_len>min_len)
            {
                if(!line_micp.count(line_len))
                {
                    //wrap the content into the line_info to insert

                    content=(char *)malloc(sizeof(line)*(strlen(line)+1));
                    strcpy(content, line);
                    line_info=(line_infoT *)malloc(sizeof(line_infoT));
                    line_info->number=++number;
                    line_info->content=content;
                    line_micp.insert(micp::value_type(line_len, line_info));
                    if(!test_10)//if micp has less than 10 members, we don't need to do these steps

                    {
                        //remember to free the member which you want to erase

                        free((line_micp.begin())->second->content);
                        (line_micp.begin())->second->content=NULL;
                        free((line_micp.begin())->second);
                        (line_micp.begin())->second=NULL;
                        line_micp.erase(line_micp.begin());
                        //updata the min_len

                        min_len=(line_micp.begin())->first;
                    }
                    else
                    {
                        //updata the micp_size

                        micp_size++;
                        test_10=micp_size<10?true:false;
                    }
                }
            }
    }
    //display the 10 members in micp and in the same time, free them

    printf("the top 10 lines are:\n");
    printf("len \tnumb\tcontent\n");
    for(int i=0;i<10;i++)
    {
        printf("%4d\t%4d\t%s\n", (line_micp.begin())->first, (line_micp.begin())->second->number, (line_micp.begin())->second->content);
        free((line_micp.begin())->second->content);
        (line_micp.begin())->second->content=NULL;
        free((line_micp.begin())->second);
        (line_micp.begin())->second=NULL;
        line_micp.erase(line_micp.begin());
    }
    fclose(data);
    data=NULL;
    line=temp_line;
    free(line);
    line=NULL;
}

阅读(1115) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~