数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
用VS.Net编写扩展存储过程(三,完)

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

昨天忙着写这个,没看奥运会,刚知道老郭和小吴又让外国人郁闷了一把。不知道奥委会是不是又要对跳水改变规则哪?

在上一节,我们把含有两车站的所有火车ID和路线信息分别读入了int *TrainID和CHAR** ppcStations,完成了最后一次读入数据的过程,下面就要处理这些数据以获得结果……就要结束了,前途是光明的,道路是平坦的……风是背后吹来的……有MM在身边陪着的……晕,忘了告诉各位兄弟,小弟现在不吃西红柿了,改吃鸡蛋,请多多关照积极配合,谢谢~~~

第三步,寻找最短的路线

显然,首先要对路线信息的字符串做分词处理,知道了从一站到下一站需要多长时间,才可能计算最短路线。本文中将用.Net类库中提供的正则式类来分割这些字符串……当然用普通方法也完全可以处理。

要使用正则式类,就要用到托管代码,我还是只讲应用,不讲原理。对托管代码工作机制感兴趣的朋友,请参阅MSDN中的托管编程部分。

先选择xsTrainQuery项目的属性,将“配置属性”下“常规”中的“使用托管扩展”改为“是”,随后在proc.cpp中加入如下预编译头:

#using
#using
using namespace System;
using namespace System::Text::RegularExpressions;
对于char*字符串,必须转化为托展字符串类型,即System::String*指针,才能用正则式类处理。我是用这样的方式把char*转化为System::String*:
System::String *newStr = System::Text::Encoding::Unicode->GetString(System::Text::Encoding::Unicode->GetBytes(oldStr));
现在就到了这一步的重头戏——正则式分词。不知道大家有没有掌握.Net的正则式,如果象我一样是菜鸟,还是让MSDN随时待命吧~
{
    // 把起点和终点站由PBYTE转化为System::String*
    System::String *strStart = System::Text::Encoding::Unicode->GetString(System::Text::Encoding::Unicode->GetBytes((PCHAR)pbStart));
    System::String *strEnd = System::Text::Encoding::Unicode->GetString(System::Text::Encoding::Unicode->GetBytes((PCHAR)pbEnd));

    // 定义正则式模式
    // 用两个\\,是因为|在正则式中有特定含义,必须在|前加上\转义,而\\代表了\
    Regex *r = new Regex(S"( ?:\\|(.+?),(.+?)小时)+\\|");

    // 定义循环中将用到的变量
    int iOldTime = INT_MAX;
    int nFastest = 0;

    // 万事俱备,开始处理ppcStations指针数组
    for (int i=0; i    {
        // 用r来匹配ppcStations[i]
        Match *m = r->Match(ppcStations[i]);
        // 所有站点的匹配组
        System::Text::RegularExpressions::Group *gStation = m->Groups->get_Item(1);
        // 所有时间的匹配组,与站点匹配组按顺序一一对应
        System::Text::RegularExpressions::Group *gTime = m->Groups->get_Item(2);

        // 定义ppcStations[i]所代表的路线所需时间
        int iNewTime = 0;
        // 定义是否已经找到起点站的BOOL变量
        BOOL bStartFound = FALSE;

        // j从0到gStation中捕获的个数,即总共捕获到多少个站点
        for (int j=0; jCaptures->Count; ++j)
        {
            if ( !bStartFound )
            {
                // 如果尚未找到起点,则判断当前捕获站点是否为起点
                if ( gStation->Captures->get_Item(i)->Value->Trim()->Equals(strStart->Trim()) )
                     bStartFound = TRUE;
                // 即使找到了起点,也直接continue,因为起点站对应的时间对运算无意义
                continue;
            }
            else
            {
                 // 已经找到起点站,开始累加路线时间
                 iNewTime += Int32::Parse(gTime->Captures->get_Item(i)->Value->Trim());
                 // 看当前捕获站点是否为终点,若是则退出for循环
                 if ( gStation->Captures->get_Item(i)->Value->Trim()->Equals(strEnd->Trim()) )
                    break;
            }
        }
        // for循环已退出,比较iNewTime和iOldTime,并记录较小的路线索引
        if ( iNewTime < iOldTime )
        {
             iOldTime = iNewTime;
             nFastest = i;
        }
    }
    // 现在,nFastest代表了最短路线的索引,iOldTime则代表所需的最短时间
}

终于找到了最短路线和最短时间,工作完成了!运行运行…………期待…………期待…………焦虑…………疑惑…………不对啊,怎么没有结果?

哦!忘了最后一步,还需要把结果传出……

第四步,也是最后一步,传出结果

结果定义为这样的形式——'车ID,需时',生成结果就很简单了:
{
    // 定义一个255字节的数组,较容易处理
    CHAR pcResult[255];
    sprintf(pcResult, "火车ID为%d,需时%d小时", piTrainID[nFastest], iOldTime);
}

怎样把pcResult送出去?这就用到了srv.h中定义的srv_paramsetoutput方法,其格式如下:

int srv_paramsetoutput (
SRV_PROC * srvproc,
int n,
BYTE * pbData,
ULONG cbLen,
BOOL fNull );

其中,n代表是第几个参数,pbData代表参数数据,cbLen代表参数长度(字节),
若fNull设置为TRUE,则此出参将被强制设为NULL.

大家肯定注意到,pbData是一个BYTE指针,于是我们还要把pcResult转换为BYTE*,这个很简单,直接显式转换即可。

设置出参的代码如下:
{
     // 得到结果的实际长度(字节数)
     int nResultLen = strlen(pcResult);
     // 传出参数
     srv_paramsetoutput(srvproc, 3, (PBYTE)pcResult, nResultLen, FALSE);
 
     // 所有的工作完成后,发出senddone信息
     srv_senddone(pSrvProc, (SRV_DONE_COUNT | SRV_DONE_MORE), 0, 1);
    }

现在工作似乎已经完成了,快拿去运行吧,嘿嘿,多运行几次……再运行几次……陶醉一下……又运行几次……然后……重启计算机,继续往下看。

上面的代码中,我们没有完全释放所分配的资源,所以每次运行都会造成内存泄漏。我们必须在代码的最后加上释放内存空间的语句,比如ppcStations, piTrainID等。

大功告成,第一个问题得到了解决。

本来还想写第二个问题的,可第二个问题和第一个问题的区别只在于第三步,即如何计算最短路线的算法上,这个,我相信我现在用的方法一定不是最好的,就不拿出来献丑了。

原来写篇文章是这么累的……




相关文章

相关软件