Rule text files to achieve data sorted according to key fields

    Quicksort (Quick Sort) is an improved sorting algorithm, the optimal average performance which is widely used in a variety of sorting algorithms. STL is to achieve the sort of a non-recursive quicksort. In the embedded platform, especially in some low-end in terms of DOS-based embedded systems, due to the age-old compiler, support for C ++ standards are a far cry from, but there can be no STL, especially in real mode, and CPU speed low system memory and storage space are in short supply in the case. Further, the DBMS is embedded in a luxury, even if there are embedded DB, but on low-end systems is difficult to be applied, a simple text Most lower end embedded devices are used to access data. Now I will achieve self-CLASS 2 for fast sorting algorithm (recursively) in a regular format text data file and output file sorted.

Code is as follows (in the Borland C ++ compiler 5.02):

#include <string.h>
#include <, iostream.h>
#include <the conio.h>
#include <stdio.h>
#include <SYS / types.h>
# the include <SYS / stat.h>
// # the include <unistd.h>

// class name: MsgPair
@ action: storing a key-value pair (int, char *)
class MsgPair
{
  public:
    ~ MsgPair ();
    MsgPair ();
    MsgPair (I int, char const * PC);
    void SetPair (int I, const char * PC);
    int No () const {return _NO;};
    void No (int I) {_NO = I;};
    const char * Msg () const {return the _msg;};
    void Msg (const char PC *);
    MsgPair & operator = (MsgPair & MP);
   
  Private:
    int _NO;
    char * the _msg;   
};

/* public function */

MsgPair::~MsgPair()
{
  delete[] _msg;
  _msg = NULL;
  _no = 0;
}

MsgPair::MsgPair()
{
  _no = 0;
  _msg = NULL;
}

MsgPair::MsgPair(int i, const char* pc)
{
  SetPair(i, pc);
}

// = operator overloading, assigned to this object (deep copy)
MsgPair & MsgPair :: operator = (MP & MsgPair)
{
  IF (MP & == NULL)  
  {
    Delete [] the _msg;
    the _msg = NULL;
    _NO = 0;
  }
  the else
  {
    _NO = mp._no;
    Delete [] the _msg;
    the _msg = new new char [strlen (mp._msg) +. 1];
    strcpy (the _msg, mp._msg);
  }
  return * the this;
}

// copy back to the key-value pair (deep copy)
void MsgPair :: SetPair (I int, char const * PC)
{
  _NO = I;
  the _msg = NULL;
  Msg (PC);
}

// Set _msg private field (deep copy)
void MsgPair :: Msg (const char * PC)
{
  IF (_msg = NULL!) 
    Delete [] _msg;
  IF (strlen (PC)> 0)
  {
    _msg = new new char [ strlen (PC) + 1'd];
    strcpy (the _msg, PC);
  }
}
/ * End of Class MsgPair * /


// class name: MsgQuickSort
@ effect: the data to a text file with a quick sort rules sorting, the sorted data is output to the specified file
class MsgQuickSort
{
  public:
    ~ MsgQuickSort ();
    MsgQuickSort (const char * filename, int LINELENGTH, int msgOffset, int MsgLength);
    void SetMsgFormat (const char * filename, int LINELENGTH, int msgOffset, int MsgLength);
    int LoadMsgFromFile ();   
    int ParseMsg (the FILE * FP);
    Long the GetFileSize (the FILE * FP);
    int the Sort ();
    void displayall ();   
    int the SaveToFile (const char * filename);
   
  Private:
    int the Partition (MsgPair * (& MP), int Low, int High);
    void qsort (MsgPair * (& MP), int Low, int High) ;
    unsigned int _msgPairNum;
    MsgPair* _pMsgPair;      
    const char* _filename;
    int _lineLength, _msgOffset, _msgLength;
};

/* public function */

MsgQuickSort::~MsgQuickSort()
{
  delete[] _filename;
  _filename = NULL;
  delete[] _pMsgPair;
  _pMsgPair = NULL;
}
MsgQuickSort::MsgQuickSort(const char* filename, int lineLength, int msgOffset, int msgLength)
{
  _pMsgPair = NULL;
  _filename = NULL;
  _msgPairNum = 0;
  SetMsgFormat(filename, lineLength, msgOffset, msgLength);
}

// rule setting data (filename = filename; lineLength = line length (note line terminator); msgOffset = offset keywords; msgLength = key length)
void MsgQuickSort :: SetMsgFormat (const char * filename, int LINELENGTH, int msgOffset, int MsgLength)
{
  _lineLength = LINELENGTH;
  _msgOffset = msgOffset;
  _msgLength = MsgLength; 
 
  ! IF (_filename = NULL)
  {
    Delete [] _filename;
    _filename = NULL;
  }
  _filename = new new char [strlen (filename) +. 1];
  strcpy ((char *) _ filename, filename); 
}

// Load the file key from the data segment into memory
int MsgQuickSort :: LoadMsgFromFile ()
{
  the FILE * FP;
  int = 0 RET;
  FP = the fopen (_filename, "RB");
  IF (! FP = NULL)
  {
   RET ParseMsg = (FP);
    fclose (FP);
  } 
  return RET;
}

// get file size
Long MsgQuickSort :: the GetFileSize (the FILE * FP)
{
 struct STAT buf;
 FSTAT (the fileno (FP), & buf);
 return buf.st_size;
}

// extracting keywords stored in memory
int MsgQuickSort :: ParseMsg (the FILE * FP)

  Long fileSize = 0;
  char * MSG = NULL;

  if(fp == NULL)
    return -1;

  msg = new char[_msgLength + 1];
  fileSize = GetFileSize(fp);
  _msgPairNum = (fileSize / _lineLength);   //一共多少行
  _pMsgPair = new MsgPair[_msgPairNum];
  for(unsigned int i = 0; i < _msgPairNum; i++)
  {
    memset(msg, 0, _msgLength + 1);
    fseek(fp, long((i * _lineLength) + _msgOffset), SEEK_SET);
    fread(msg, 1, _msgLength, fp);
    _pMsgPair[i].SetPair(i, msg);     //MsgPair从第0开始,到uiMaxItem - 1结束
  }
  delete[] msg;
  return 1;
}

// key data currently in memory, and the line number corresponding to its loading (from the zero line)
void MsgQuickSort :: displayall ()
{
  for (unsigned int I = 0; I <_msgPairNum; I ++)
  {
    the printf ( "[% 05d]: [% S] \ R & lt \ n-", _pMsgPair [I] .no (), _pMsgPair [I] a .msg ());
  }
}

// 保存当前的顺序到文件(未执行排序函数将保持原顺序)
int MsgQuickSort::SaveToFile(const char* saveFilename)
{
  char *msg = NULL;
  FILE *fp_save;
  FILE *fp_from;
  unlink(saveFilename);
  fp_save = fopen(saveFilename, "ab");
  fp_from = fopen(_filename, "rb");
  if(fp_save == NULL)
    return -1;
  else if(fp_from == NULL)
  {
    fclose(fp_save);
    return -1;
  }
  msg = new char[_lineLength + 1];
  for(unsigned int i = 0; i < _msgPairNum; i++)
  {
    memset(msg, 0, _msgLength + 1);
    fseek(fp_from, long(_pMsgPair[i].No() * _lineLength), SEEK_SET);
    fread(msg, 1, _lineLength, fp_from);
    fwrite(msg, 1, _lineLength, fp_save);
  }
  delete[] msg;
  fclose(fp_save);
  fclose(fp_from);
  return 1;
}

// Data sorting
int :: MsgQuickSort the Sort ()
{
  qsort (_pMsgPair, 0,-_msgPairNum. 1);
}

/ * Private function * /
// sort quick sort trip
int :: MsgQuickSort the Partition (MsgPair * (& MP), Low int, int High)
{
  MsgPair pivotkey;
  pivotkey MP = [Low];

  while(low<high)
  {   
    while(low<high && strcmp(mp[high].Msg(), pivotkey.Msg()) >= 0)
    {
      --high;
    }
    mp[low] = mp[high];
    while(low<high && strcmp(mp[low].Msg(), pivotkey.Msg()) <= 0)
    {
      ++low;
    } 
    mp[high] = mp[low];
  }
  mp[low] = pivotkey;
  return low;
}

// recursive function quicksort
void MsgQuickSort :: qsort (MsgPair * (& MP), Low int, int High)
{
  IF (Low <High)
  {
    int = pivotloc the Partition (MP, Low, High); 
    qsort (MP, Low, . 1-pivotloc);
    qsort (MP, pivotloc +. 1, High);
  }
}

/* End Of Class MsgQuickSort */

/ * The Test * /
int main ()
{
 
  MsgQuickSort MQS ( "msg.txt", 41 is, 0, 10); // be ranked documents msg.txt; 41 bytes per line; keyword line offset 0, length of 10 bytes
  mqs.LoadMsgFromFile (); // file keywords loaded into memory
  mqs.Sort (); // quicksort (here sorted by ASCII code keywords)
  mqs.DisplayAll (); // current keyword display order (sorted)
  mqs.SaveToFile ( "sortmsg.txt"); // save data sorted according to the key file sortmsg.txt
  
  getch ();
  return 0;
}

msg.txt example :
7905C5AEFC06120720503312018162236739999
7903FADFF106120720504012018162236739999
7F7F56E23006120720505212018162236739999
7A9686FB5106120720505412018162236739999
7A4C7B723F06120720505512018162236739999
79093698CA06120720505612018162236739999
7A9686FB5106120720505412018162236739999
7A4C7B723F06120720505512018162236739999
79093698CA06120720505612018162236739999
7A9686FB5106120720505412018162236739999
7A4C7B723F06120720505512018162236739999

sortmsg.txt输出:
7903FADFF106120720504012018162236739999
7905C5AEFC06120720503312018162236739999
79093698CA06120720505612018162236739999
79093698CA06120720505612018162236739999
7A4C7B723F06120720505512018162236739999
7A4C7B723F06120720505512018162236739999
7A4C7B723F06120720505512018162236739999
7A9686FB5106120720505412018162236739999
7A9686FB5106120720505412018162236739999
7A9686FB5106120720505412018162236739999
7F7F56E23006120720505212018162236739999

Achievement Process:
1, quick sort (Quick Sort) the highest average time efficiency in various sorting programs.
2, since the embedded systems with multiple FLASH (mainly the NAND and NOR) access, read and write FLASH should be reduced as much as possible, in the high memory efficiency and wear rate. Therefore, using the original document reading line number corresponding to the keyword + sorted manner into memory process, and then sorted according to the order, the original document by a corresponding line number, lookup output after storage. Generally, even low-end embedded, after the DOS system, the total memory space should be about 512KB, FLASH also should use at least 1MB (to ensure the normal operating system and main storage), according to the present example, 10 bytes keywords , assuming 1W line data, the memory for the calculation time accounting for about = 10 * 10K = 100KB.
3 In addition, under the old compiler, there is no simple and readily available solution to avoid memory fragmentation (mainly refers to the external fragmentation) allocation tool, based on this case, in the life cycle MsgQuickSort as much as possible not to insert other to dynamic memory allocation statement, this can also reduce the risk of memory fragmentation (external fragmentation) produced in the process.

Reproduced in: https: //www.cnblogs.com/leaway/archive/2007/01/10/616522.html

Guess you like

Origin blog.csdn.net/weixin_34060299/article/details/93840424