国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

用VS.Net編寫擴展存儲過程(三,完)

2024-07-21 02:07:32
字體:
來源:轉載
供稿:網友

昨天忙著寫這個,沒看奧運會,剛知道老郭和小吳又讓外國人郁悶了一把。不知道奧委會是不是又要對跳水改變規則哪?

在上一節,我們把含有兩車站的所有火車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等。

大功告成,第一個問題得到了解決。

本來還想寫第二個問題的,可第二個問題和第一個問題的區別只在于第三步,即如何計算最短路線的算法上,這個,我相信我現在用的方法一定不是最好的,就不拿出來獻丑了。

原來寫篇文章是這么累的……


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宁蒗| 江源县| 洮南市| 廉江市| 濮阳市| 芦溪县| 拜泉县| 商丘市| 云南省| 台安县| 安图县| 榕江县| 孟村| 托里县| 潜山县| 通海县| 富民县| 灵石县| 织金县| 休宁县| 兰考县| 博野县| 潢川县| 水城县| 永嘉县| 临沭县| 云安县| 丘北县| 若羌县| 油尖旺区| 莲花县| 嘉善县| 田阳县| 遂川县| 扎赉特旗| 文成县| 增城市| 洛川县| 寻甸| 申扎县| 柘城县|