クイックソート(クイックソート)を向上ソートアルゴリズム、広くソートアルゴリズムの様々な使用される最適な平均性能です。STLは、非再帰的クイックソートのソートを達成することです。、DOSベースの組み込みシステムの観点から、特にいくつかのローエンドの組み込みプラットフォームでは、原因古来のコンパイラに、C ++標準規格のサポートは程遠いですが、特にリアルモード、およびCPU速度で、何のSTLはありえません低いシステムメモリと記憶空間は、ケースに不足しています。さらに、DBMSを組み込みDBがあっても、贅沢に埋め込まれているが、ローエンドシステムに簡単なテキストのほとんど下端組み込みデバイスがデータにアクセスするために使用され、適用することは困難です。今私は、高速ソート定型テキストデータファイルと出力ファイル内のアルゴリズムを(再帰的に)ソートに自己CLASS 2を実現します。
コードは次のようである(ボーランドC ++コンパイラ5.02で):
の#include <string.hの>
の#include <、でiostream.h>
の#include <conio.h>
書式#include <stdio.hに>
する#include <SYS / types.h>に
#含める<SYS / stat.h>
//#含める<unistd.h>
//クラス名:MsgPair
@アクション:キーと値のペアを格納し(int型、char型*)
クラスMsgPair
{
パブリック:
〜MsgPair();
MsgPair();
MsgPair(私はint型、char型のconst * PC);
無効SetPair(int型I、CONSTするchar * PC);
INTなし()constは{戻り_NO;};
;いいえ(INT I){_NO = I;}無効
CONST CHAR *メッセージ()constは{_msgを返すを;};
メッセージ(CONSTチャーが無効PC用*);
MsgPair&演算子=(MsgPair&MP);
プライベート:
int型_NO;
CHAR * _msg;
};
/ *パブリック関数* /
MsgPair ::〜MsgPair()
{
削除[] _msg。
_msg = NULL;
_no = 0。
}
MsgPair :: MsgPair()
{
_no = 0。
_msg = NULL;
}
MsgPair :: MsgPair(int型I、のconstのchar *のPC)
{
SetPair(I、PC);
}
このオブジェクト(ディープコピー)に割り当て// =演算子のオーバーロード、
MsgPair&MsgPair ::演算子=(MP&MsgPair)
{
IF(MP&== NULL)
{
[] _msg削除;
_msg = NULL;
_NO = 0;
}
そうし
{
_NO = mp._no;
[] _msg削除;
_msg =新しい新しいCHAR [strlenを(mp._msg)+ 1];
(_msg、mp._msg)strcpyの;
}
*これを返します;
}
//バックキーと値のペア(ディープコピー)にコピーし
、ボイドMsgPair :: SetPair(私はint型、char型のconst * PC)
{
_NO = I;
_msg = NULL;
メッセージ(PC);
}
//は_msgプライベートフィールド(深いコピー)を設定し
、ボイドMsgPairを::メッセージ(のconst char型* PC)
{
IF(_msg = NULL!)
;削除[] _msg
IF(STRLEN(PC)> 0)
{
[_msg =新しい新しい文字STRLEN(PC)+ +1];
strcpyの(_msg、PC);
}
}
クラスMsgPairの/ *終了* /
//クラス名:MsgQuickSort
@効果:ソートクイックソートのルールをテキストファイルにデータを、ソートされたデータは、指定したファイルに出力され
たクラスMsgQuickSort
{
パブリック:
〜MsgQuickSort();
MsgQuickSort(のconstのchar *ファイル名、int型LINELENGTH、int型msgOffset、int型MsgLength);
無効SetMsgFormat(のconstのchar *ファイル名、int型LINELENGTH、int型msgOffset、int型MsgLength);
; LoadMsgFromFile()int型
int型ParseMsg(FILE * FP)を、
ロングGetFileSize(FILE * FP);
ソートint型();
無効displayall();
SaveToFileメソッド(のconstのchar *のファイル名)のint;
プライベート:
パーティションint型(MsgPair *(&MP)、ローINT、ハイINT);
空のqsort(MsgPair *(&MP)、ローINT、ハイINT) ;
unsigned int型_msgPairNum。
MsgPair * _pMsgPair。
constのchar *の_filename。
int型_lineLength、_msgOffset、_msgLength。
}。
/ *パブリック関数* /
MsgQuickSort ::〜MsgQuickSort()
{
削除[] _filename。
_filename = NULL;
[] _pMsgPairを削除します。
_pMsgPair = NULL;
}
MsgQuickSort :: MsgQuickSort(CONST文字*ファイル名、行の最大長INT、INT msgOffset、INT msgLength)
{
_pMsgPair = NULL;
_filename = NULL;
_msgPairNum = 0。
SetMsgFormat(ファイル名、行の最大長、msgOffset、msgLength)。
}
//ルール設定データ(ファイル名=ファイル名;行の最大長=ラインの長さ(ノート回線終端); msgOffset =キーワードをオフセット; msgLength =キーの長さ)
、ボイドMsgQuickSort :: SetMsgFormat(のconstのchar *ファイル名、int型のLINELENGTH、 INT msgOffset、INT MsgLength)
{
_lineLength = LINELENGTH;
_msgOffset = msgOffset;
_msgLength = MsgLength;
!IF(_filename = NULL)
{
[] _filename削除;
_filename = NULL;
}
_filename =新しい新しいCHAR [strlenを(ファイル名)+ 1]。
strcpyの((CHAR *)_ファイル名、ファイル名);
}
//メモリにデータセグメントからのファイルのキーをロード
int型MsgQuickSort :: LoadMsgFromFile()
{
FILE * FP;
int型= 0 RET;
FPは、関数fopen(_filename、 "RB")を=;
IF(FP = NULL!)
{
RET ParseMsg =(FP)、
FCLOSE(FP);
}
戻りRET;
}
//取得したファイルサイズ
ロングMsgQuickSort :: GetFileSize(FILE * FP)
{
構造体STATのBUF、
FSTAT(FILENO(FP)、&BUF);
戻りbuf.st_size;
}
//メモリに格納されたキーワード抽出
INT MsgQuickSort :: ParseMsg(ファイル*のFP)
{
ロングファイルサイズ= 0;
CHAR * MSG = NULL;
(FP == NULL)であれば
リターン-1。
MSG =新しい文字[_msgLength + 1]。
ファイルサイズ= GetFileSize(FP)。
_msgPairNum =(ファイルサイズ/ _lineLength)。//一共多少行
_pMsgPair =新しいMsgPair [_msgPairNum]。
用(unsigned int型i = 0; I <_msgPairNum; iは++)
{
memsetの(MSG、0、_msgLength + 1)。
fseek関数(FP、ロング((私は_lineLengthを*)+ _msgOffset)、SEEK_SET);
関数fread(MSG、1、_msgLength、FP)。
_pMsgPair [I] .SetPair(I、MSG)。// MsgPair从第0开始、到uiMaxItem - 1结束
}
削除[] MSG。
1を返します。
}
//キー現在メモリ内のデータ、および(ゼロラインから)、その負荷に対応するライン番号
ボイドMsgQuickSort :: displayall()
{
用(unsigned int型I = 0; I <_msgPairNum; Iは++)
{
のprintf( "[%05D]:[%S] \ R&LT \ N-"、_pMsgPair [I] .NO()、_pMsgPair [I] A .MSG());
}
}
//保存当前的顺序到文件(未执行排序函数将保持原顺序)
INT MsgQuickSort :: SaveToFileメソッド(CONST文字* saveFilename)
{
文字* MSG = NULL;
FILEの*のfp_save。
FILEの*のfp_from。
(saveFilename)解除。
fp_save =用のfopen(saveFilename、 "AB")。
fp_from =のfopen(_filename、 "RB")。
(fp_save == NULL)であれば
リターン-1。
そうであれば(fp_from == NULL)
{
FCLOSE(fp_save)。
-1を返します。
}
MSG =新しい文字[_lineLength + 1]。
用(unsigned int型i = 0; I <_msgPairNum; iは++)
{
memsetの(MSG、0、_msgLength + 1)。
fseek関数(fp_from、長い(_pMsgPair [I] .NO()* _lineLength)、SEEK_SET)。
関数fread(MSG、1、_lineLength、fp_from)。
fwriteの(MSG、1、_lineLength、fp_save)。
}
[] MSGを削除します。
FCLOSE(fp_save)。
FCLOSE(fp_from)。
1を返します。
}
//データソート
INT :: MsgQuickSortソート()
{
qソート(_pMsgPair、0、-_ msgPairNum 1);
}
/ *プライベート機能* /
//ソートクイックソートの旅の
int型:: MsgQuickSortパーティション(MsgPair *(&MP)、低int型、int型ハイ)
{
MsgPairのpivotkey;
pivotkey MP = [低]。
一方(低<高)
{
一方(低<高&&のstrcmp(MP [高] .MSG()、pivotkey.Msg())> = 0)
{
--high。
}
MP [低] =融点[高]。
一方(低<高&&のstrcmp(MP [低] .MSG()、pivotkey.Msg())<= 0)
{
++低いです。
}
MP [高] =融点[低]。
}
MP [低] = pivotkey。
低返します。
}
//再帰関数のクイックソート
のボイドMsgQuickSort ::のqsort(MsgPair *(&MP)、低int型、int型ハイ)
{
IF(低<高)
{
int型= pivotlocパーティション(MP、ロー、ハイ);
のqsort(MP、低、 1-pivotloc);
qソート(MP、pivotlocの+ 1、高);
}
}
/ *クラスMsgQuickSortの終わり* /
/ *テスト* /
int型のmain()
{
MsgQuickSort MQS( "msg.txt"、41、10、0、である); //ランク付けすることがドキュメントはmsg.txt、行あたり41のバイトが、キーワードの行は、0オフセット10バイトの長さを
メモリにロード//ファイルのキーワード; mqs.LoadMsgFromFile()
mqs.Sort(); //クイックソート(ここではASCIIコードのキーワードでソート)
mqs.DisplayAll(); //現在のキーワードの表示順(ソート)
mqs.SaveToFile( "sortmsg.txt"); //保存データの並べ替えキーファイルsortmsg.txtのに従って
getchは();
戻り0;
}
msg.txt例:
7905C5AEFC06120720503312018162236739999
7903FADFF106120720504012018162236739999
7F7F56E23006120720505212018162236739999
7A9686FB5106120720505412018162236739999
7A4C7B723F06120720505512018162236739999
79093698CA06120720505612018162236739999
7A9686FB5106120720505412018162236739999
7A4C7B723F06120720505512018162236739999
79093698CA06120720505612018162236739999
7A9686FB5106120720505412018162236739999
7A4C7B723F06120720505512018162236739999
sortmsg.txt输出:
7903FADFF106120720504012018162236739999
7905C5AEFC06120720503312018162236739999
79093698CA06120720505612018162236739999
79093698CA06120720505612018162236739999
7A4C7B723F06120720505512018162236739999
7A4C7B723F06120720505512018162236739999
7A4C7B723F06120720505512018162236739999
7A9686FB5106120720505412018162236739999
7A9686FB5106120720505412018162236739999
7A9686FB5106120720505412018162236739999
7F7F56E23006120720505212018162236739999
達成プロセス:
1、クイックソート(クイックソート)様々なソートプログラムで最高の平均時間効率。
図2は、複数のFLASH(主にNANDおよびNOR)アクセスの組み込みシステムので、読み取りおよび書き込みFLASH高いメモリ効率で、可能な限り低減し、速度を着用しなければなりません。したがって、メモリのプロセスにキーワード+ソートされた方法に対応する原稿の読み取りライン数を用いて、そしてする順序に従ってソート、対応するライン番号、保存後のルックアップ出力によって原稿。一般的に、偶数ローエンドが埋め込ま、DOSシステムの後に、総メモリ容量が512キロバイトであるべきである、FLASHも、本実施例によれば、(通常のオペレーティング・システムとメインストレージを確保するため)10個のバイトのキーワードを少なくとも1メガバイトを使用する必要があります、1Wラインデータ、約= 10 * 10K = 100キロバイトを占める計算時間のためのメモリを想定。
また、図3に示すように、古いコンパイラの下で、単純なおよび容易に入手可能な溶液は、メモリの断片化を避けるためには存在しない(主に外部の断片を指す)割り当てツール、この場合に基づいて、ライフサイクルMsgQuickSortにできるだけ動的に他方を挿入しませんメモリ割当てステートメントは、これは、プロセスで製造さメモリの断片(外部断片化)の危険性を低減することができます。
ます。https://www.cnblogs.com/leaway/archive/2007/01/10/616522.htmlで再現