| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 602 人关注过本帖
标题:高手请进!一个难题求算法!真的很难!
只看楼主 加入收藏
liqingyulipeng
Rank: 1
等 级:新手上路
帖 子:63
专家分:3
注 册:2008-10-11
结帖率:77.78%
收藏
已结贴  问题点数:3 回复次数:7 
高手请进!一个难题求算法!真的很难!

题目:有一新闻报刊系统数据库,如下图所示:
报刊1            报刊2           报刊3    ……  报刊n
|                  |                |               |  
事件1    ……    事件n    ……    事件m    ……    事件t    ……

报刊1,报刊2等分别是不同的报刊,如人民日报,参考消息,环球日报等。
事件1,事件n等分别是在不同的报刊中的报道的事件。
其中所有的报刊(每个报刊都包含若干事件)是存在一个链表中的,结构如下:
Typedef struct _ST_NEWSPAPERS
{
    Unsigned int uiNewsPaperID;/*报刊号,从1到n*/
    ST_EVENT *pstEventHead;/*该指针指向本报刊中的第一个事件。*/
    struct _ST_NEWSPAPERS *pstNextNewPaper;/*指向下一个报刊*/
} ST_NEWSPAPERS;

所有的事件是存在一个数组中的(同一报刊的事件一定是存在一起的,如上图中,报刊1中报道的事件不可能出现在“事件n”及以后的位置上;并且同一报刊内的事件是按照时间从小到大排好序的),每个事件的结构如下:
Typedef struct _ST_EVENT
{
    Unsigned int uiEventID;/*事件编号*/
    Unsigned int uiTtime;/*事件发生的时间*/
    Unsigned char ucEventClass;/*事件的类别,如财经,政治,汽车,时尚等*/
} ST_EVENT;

问题来了:
    要求编写一个查询函数,函数的接口如下:
    Unsigned int QuaryEvent(unsigned char ucEventClass, unsigned int uiStartTime,
                        Unsigned int uiGetMaxEventNum, unsigned int * puiEventID);
函数说明:
    该函数中ucEventClass的所要查询的事件类别,uiStartTime是所要查询的事件的开始时间(获取到的事件发生的时间必须大于等于此时间),uiGetMaxEventNum是一次获取的事件最大个数,puiEventID是由外部传进来的一个数组的指针,由该函数内部将查询到的事件的事件号(uiEventID)存到该指针指向的空间中。
    返回值是实际查询到的事件个数

查询要求:
(1)    要求puiEventID中存的事件必须按照时间从小到大的顺序排列好,如果碰到时间相同的事件,必须按照该事件所属报刊的报刊号从小到大排列好。举个例子:
现在要求查询“财经”这个类别,发生在8点之后的新闻事件。在报刊系统数据库中,报刊1中的有一个财经新闻事件在8点半(假设为事件1),报刊2中有一个财经新闻事件在8点20(假设为事件2),报刊3中有一个财经新闻事件在8点半(假设为事件3)。
    那么最后的排序结果应该是:事件2,事件1,事件3。
(2)    要求查询具有延续性。举例说明:
现在要求查询“财经”这个类别,发生在8点之后的新闻事件。在报刊系统数据库中,报刊1中的有一个财经新闻事件在8点半(假设为事件1),报刊2中有一个财经新闻事件在8点20(假设为事件2),报刊3中有一个财经新闻事件在8点半(假设为事件3),还有另一个财经新闻发生在9点(事件4)。报刊4中有一个财经新闻发生在8点50(事件5)
第一次调用QuaryEvent查询时,uiGetMaxEventNum(最大事件个数)为3,第二次调用QuaryEvent查询时,uiGetMaxEventNum也为3
    那么第一次的查询结果应该是:事件2,事件1,事件3。函数的返回值为3
    第二次的查询结果应该是:事件5,事件4。函数的返回值为2

这个题目,我已经想了一两天了,都没有好的办法,请各位聪明的高手指教一下,提供一下思路。当然如果有相应的参考代码就更好了,呵呵。


[ 本帖最后由 liqingyulipeng 于 2010-4-14 01:23 编辑 ]
搜索更多相关主题的帖子: 难题 算法 
2010-04-14 01:20
liqingyulipeng
Rank: 1
等 级:新手上路
帖 子:63
专家分:3
注 册:2008-10-11
收藏
得分:0 
没有高手来过吗??自己顶一下
2010-04-14 09:09
mywaylgh
Rank: 8Rank: 8
来 自:厨房
等 级:蝙蝠侠
威 望:5
帖 子:188
专家分:729
注 册:2010-3-10
收藏
得分:1 
舍不得孩子套不了狼啊

人生就像茶几 上面放着许多杯具

人生也像厨房 里面总有一些洗具
2010-04-14 09:16
liqingyulipeng
Rank: 1
等 级:新手上路
帖 子:63
专家分:3
注 册:2008-10-11
收藏
得分:0 
楼上的什么意思啊?是说我分给的太少了吗? 我已经把我的全部分都贡献出来了,呵呵,虽然很少
2010-04-14 11:44
brackenbo
Rank: 1
等 级:新手上路
帖 子:6
专家分:5
注 册:2010-4-9
收藏
得分:1 
我不是高手,自己试着来做了一下,还大家多多指教。

其中有一部分是测试用例。时间我直接用数字表示( 8:30 == 830 )

-------------------头文件 newspaper.h

#ifndef NEWS_PAPER_H_
#define NEWS_PAPER_H_

enum { entertament, political, economic, science };//将类别作为枚举类型(娱乐,政治,经济,科学)

typedef struct EVENT
{
    unsigned int eventID; //事件ID
    unsigned int eventTime;//事件发生的时间(我在这里用简单的数字来表示,如8:30就是830)
    unsigned char eventClass;//事件的类别
}EVENT;

typedef struct NEWSPAPERS
{
    unsigned int newsPaperID;//报纸的ID
    EVENT *eventHead;//所包含的事件
    struct NEWSPAPERS *nextNewsPaper;
}NEWSPAPERS;

void Init();
void Clear();
unsigned int QuaryEvent( unsigned char eventClass, unsigned int startTime,
                        unsigned int getMaxEventNum, unsigned int *peventID );


#endif


----------------------------------------------------------------------------------------

---------------------------------主文件newspaper.c
#include <stdio.h>
#include "newspaper.h"

unsigned int outPutEventID[100] = { 0 };//存储满足条件事件ID的数组


//以下这部分为建立一个测试用的链表,以便后面的测试用例来测试

NEWSPAPERS *phead = NULL; //链表的头指针

//链表中的四个节点
NEWSPAPERS news1;
NEWSPAPERS news2;
NEWSPAPERS news3;
NEWSPAPERS news4;

//每个节点上对应的事件数组
EVENT eventArrFir[20] = { 0 };
EVENT eventArrSec[20] = { 0 };
EVENT eventArrThi[20] = { 0 };
EVENT eventArrFou[20] = { 0 };


//初始化链表
void Init()
{

    eventArrFir[0].eventID = 0;
    eventArrFir[0].eventClass = political;
    eventArrFir[0].eventTime = 830;

    eventArrFir[1].eventID = 1;
    eventArrFir[1].eventClass = entertament;
    eventArrFir[1].eventTime = 940;

    eventArrSec[0].eventID = 3;
    eventArrSec[0].eventClass = entertament;
    eventArrSec[0].eventTime = 820;
   
    eventArrSec[1].eventID = 4;
    eventArrSec[1].eventClass = economic;
    eventArrSec[1].eventTime = 1000;

    eventArrThi[0].eventID = 5;
    eventArrThi[0].eventClass = entertament;
    eventArrThi[0].eventTime = 820;
   
    eventArrThi[1].eventID = 6;
    eventArrThi[1].eventClass = political;
    eventArrThi[1].eventTime = 900;

   
    eventArrFou[0].eventID = 9;
    eventArrFou[0].eventClass = science;
    eventArrFou[0].eventTime = 820;
   
    eventArrFou[1].eventID = 10;
    eventArrFou[1].eventClass = political;
    eventArrFou[1].eventTime = 900;

    news1.newsPaperID = 0;
    news1.eventHead = eventArrFir;
    news1.nextNewsPaper = &news2;

    news2.newsPaperID = 1;
    news2.eventHead = eventArrSec;
    news2.nextNewsPaper = &news3;

    news3.newsPaperID = 2;
    news3.eventHead = eventArrThi;
    news3.nextNewsPaper = &news4;

    news4.newsPaperID = 1;
    news4.eventHead = eventArrFou;
    news4.nextNewsPaper = NULL;

    phead = &news1;
}


//Clear 清除上一次满足条件的事件ID
void Clear()
{
    int i = 0;

    for ( i = 0; i < 100; i++ )
    {
        outPutEventID[i] = 0;
    }
}

//所要求的函数
unsigned int QuaryEvent( unsigned char eventClass, unsigned int startTime,
                        unsigned int getMaxEventNum, unsigned int *peventID )
{
    int i = 0;
    unsigned int tmpEventClass = 0;//链表中事件的类别
    unsigned int tmpStarTime = 0;//链表中的时间
    unsigned int count = 0;
    NEWSPAPERS *pnewspaper = phead;

    while ( pnewspaper != NULL )
    {
        
        for ( i = 0; i < 2; i++ )
        {
            tmpEventClass = pnewspaper->eventHead[i].eventClass;
            tmpStarTime = pnewspaper->eventHead[i].eventTime;
            
            if ( ( tmpEventClass == eventClass ) && ( tmpStarTime >= startTime ) && ( count < getMaxEventNum ) )
            {
                peventID[count++] = pnewspaper->eventHead[i].eventID;

                if ( count == getMaxEventNum )
                {
                    phead = pnewspaper->nextNewsPaper;
                    return count;
                }
            }
        }

        pnewspaper = pnewspaper->nextNewsPaper;
    }
    return count;
}

----------------------------------------------------------------
--------------------------测试文件testnewspaper.c
#include <stdio.h>
#include <assert.h>
#include "newspaper.h"

extern NEWSPAPERS news1;
extern NEWSPAPERS news2;
extern NEWSPAPERS news3;
extern NEWSPAPERS news4;
extern EVENT eventArrFir[20];
extern EVENT eventArrSec[20];
extern EVENT eventArrThi[20];
extern EVENT eventArrFou[20];

extern unsigned int outPutEventID[100];

extern NEWSPAPERS *phead;

Test_InitEvent()//测试初始化函数
{
    Init();
    assert( eventArrFou[1].eventID == 10 );
    assert( news4.eventHead->eventID == 9 );
    assert( news1.nextNewsPaper->nextNewsPaper->newsPaperID == 2 );
    assert( news1.nextNewsPaper->nextNewsPaper->eventHead[1].eventClass == political );
}

void Test_QuaryEvent()
{
    unsigned int num = 0;

    Init();
    num = QuaryEvent( entertament, 800, 2, outPutEventID );//按要求得到返回值
    assert( num == 2 );
    assert( outPutEventID[0] == 1 );
    assert( outPutEventID[1] == 3 );
    assert( outPutEventID[2] == 0 );//由于存储了满足条件的2个ID,所以第3个以后均为0;

    Clear();//清空前面存储的ID
    num = QuaryEvent( entertament, 800, 2, outPutEventID );
    assert( num == 1 );
    assert( outPutEventID[0] == 5 );
    assert( outPutEventID[1] == 0 );//由于存储了满足条件的2个ID,所以第2个以后均为0;
    assert( outPutEventID[2] == 0 );
}

void Test_QuaryEvent1()
{
    unsigned int num = 0;
   
    Clear();
    Init();
    num = QuaryEvent( political, 830, 2, outPutEventID );
    assert( num == 2 );
    assert( outPutEventID[0] == 0 );
    assert( outPutEventID[1] == 6 );
    assert( outPutEventID[2] == 0 );

    Clear();
    num = QuaryEvent( political, 830, 2, outPutEventID );
    assert( num == 1 );
    assert( outPutEventID[0] == 10 );
    assert( outPutEventID[1] == 0 );
    assert( outPutEventID[2] == 0 );

}

int main()
{
    Test_InitEvent();
    Test_QuaryEvent();
    Test_QuaryEvent1();

    return 0;
}
--------------------------------------------------------------------------------

2010-04-14 14:02
liqingyulipeng
Rank: 1
等 级:新手上路
帖 子:63
专家分:3
注 册:2008-10-11
收藏
得分:0 
楼上的兄弟辛苦了!你的代码思路清晰,也十分规范,模块意识也强,值得我们大家学习!
不过没有满足第一个查询要求,没有对事件按时间先后顺序来获取,这正是这个题的难点所在。
2010-04-14 16:00
brackenbo
Rank: 1
等 级:新手上路
帖 子:6
专家分:5
注 册:2010-4-9
收藏
得分:0 
哦 我修改下
2010-04-14 16:11
liqingyulipeng
Rank: 1
等 级:新手上路
帖 子:63
专家分:3
注 册:2008-10-11
收藏
得分:0 
我似乎有点思路了,但是还没完全想清楚,等整理好了,就发上来,供大家参考
2010-04-14 22:12
快速回复:高手请进!一个难题求算法!真的很难!
数据加载中...
 
   



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

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