九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

我自己学习C++编写的常用函数,类,模版 最近修改日期:2008年3月26日


鉴于个人习惯,将所有的文件都放到了jtianling目录下,一般的函数放到jtianling.hjtianling.cpp中,其他的分类按文件放置,这样要包含文件就需要用include jtianling/jtianling.h形式包含,而且要在设置里面将jtianling这个目录包含进去

 

 

jtianling.h

———————————————————————————————

//-------Created By 九天雁翎(jtianling) Email:jtianling@gmail.com

//-------最后修改时间:3.26

//这个小库为了方便,特化了mapmultimap所以包含进了<map>

//因为需要string和算法,包含了<algorithm>,<string>

//做这个库的目的本来就是简化一些学习C++的过程

//所以至于效率和文件的大小都没有那么太在乎了,毕竟不是工业级的应用:)

//最近在其中加入了算法效率比较的函数和随机数组创建函数

#ifndef JTIANLING_H

#define JTIANLING_H

 

#include <iostream>

#include <algorithm>

#include <string>

#include <map>

#include <vector>

 

namespace jtianling

{

//容器输出部分

 

//以容器为输入的简化函数,第二参数为前置的string,默认为空

   template <typename T>

   void PrintCon(const T &orig, const std::string &str = "")

   {

      std::cout << str;

      typename T::const_iterator it;

      for(it = orig.begin(); it != orig.end(); ++it)

      {

         std::cout << *it <<" ";

      }

      std::cout << std::endl;

   }

 

//特化mapmultimap的模板,因为map,multimap的迭代器调用与一般容器有所不同

   template<typename T1, typename T2>

   void PrintCon(const std::map<T1, T2> &origMap,

                const std::string &str = "")

   {

      std::cout << str;

      typename std::map<T1, T2>::const_iterator it;

      for(it = origMap.begin(); it != origMap.end(); ++it)

      {

         std::cout << it->first << ":" << it->second << ";  ";

      }

      std::cout << std::endl;

   }

 

   template<typename T1, typename T2>

   void PrintCon(const std::multimap<T1, T2> &origMultimap,

                const std::string str = "")

   {

      std::cout << str;

      typename std::multimap<T1, T2>::const_iterator it;

      for(it = origMultimap.begin(); it != origMultimap.end(); ++it)

      {

         std::cout << it->first << ":" << it->second << ";  ";

      }

      std::cout << std::endl;

   }

 

//以参数数量不同,重载容器输出函数,以迭代器为输入,方便输出容器的一部份甚至数组,

//第三参数为前置的string,默认为空,因为输出部分map,multimap个人较少用到,所以不特

//化了,有需要的可以自己仿照特化响应模板

   template <typename Iter>

   void PrintCon(Iter itBegin, Iter itEnd, const std::string &str = "")

   {

      std::cout << str;

      for( NULL; itBegin != itEnd; ++itBegin)

      {

         std::cout << *itBegin << " ";

      }

      std::cout << std::endl;

   }

 

 

//-------------------------------------------------------------------

//时间获取部分

   double GetTime(); //使用高精度计时器

 

   //因为这里主要是比较不同算法的实现,所以这里不区分算法及其实现,都称为算法

   //比较算法的函数,其中算法函数的参数为数组(array)和整数(int)

   //简写为AI,为了防止混乱,这里我没有使用函数的重载

   //准备以后有新的不同参数的算法时再加入新的比较函数

   //方便最后查看对比我没有使用常规的屏幕输出而是输出到文件

   //输出文件名为CompareAlogorithmAIResult.txt

   //而且此文件可以用Excel打开,比较清晰,方便保存

   //比较函数的参数解释如下:

   //第一参数:各算法的用vector<>表示的函数指针数组

   //第二参数:vector<int>表示的一系列算法函数第二参数,用以做算法增长比较

   //主要注意的是,这里的第二参数实际也是算法函数第一参数数组的大小

   typedef void (*pfAI)(int [], int);

   void CompareAlgorithmAI(const std::vector<pfAI> &pfAIVec,const std::vector<int>& vec);

 

 

   //比较算法的函数,其中算法函数的参数为整数(int)

   //简写为I,方便最后查看对比我没有使用常规的屏幕输出而是输出到文件

   //输出文件名为CompareAlogrithmIResult.txt

   //而且此文件可以用Excel打开,比较清晰,方便保存

   //比较函数的参数解释如下:

   //第一参数:各算法的用vector<>表示的函数指针数组,

   //第二参数:vector<int>表示的一系列算法函数第二参数,用以做算法增长比较

   typedef void (*pfI)(int);

   void CompareAlgorithmI(const std::vector<pfI> &pfIVec,const std::vector<int>& vec);

 

}//end of jtianling namespace

#endif

 

jtianling.cpp

//-------Created By 九天雁翎(jtianling) Email:jtianling@gmail.com

//-------最后修改时间:.3.26

 

#include "jtianling.h"

#include <iomanip>

#include <fstream>

#include "windows.h"

namespace jtianling

{

   double GetTime() //使用高精度计时器

   {     

       static LARGE_INTEGER s_freq;

       LARGE_INTEGER performanceCount;

       double t;

       if (s_freq.QuadPart==0)

       {

              if ( !QueryPerformanceFrequency( &s_freq))

                     return 0;

       }

      

       QueryPerformanceCounter( &performanceCount );

       t=(double)performanceCount.QuadPart / (double)s_freq.QuadPart;

       return t;

   }

 

   //因为这里主要是比较不同算法的实现,所以这里不区分算法及其实现,都称为算法

   //比较算法的函数,其中算法函数的参数为数组(array)和整数(int)

   //简写为AI,为了防止混乱,这里我没有使用函数的重载

   //准备以后有新的不同参数的算法时再加入新的比较函数

   //比较函数的参数解释如下:

   //第一参数:各算法的用vector<>表示的函数指针数组

   //第二参数:vector<int>表示的一系列算法函数第二参数,用以做算法增长比较

   //主要注意的是,这里的第二参数实际也是算法函数第一参数数组的大小

   void CompareAlgorithmAI(const std::vector<pfAI> &pfAIVec,const std::vector<int>& vec)

   {

      double timeInAll = GetTime();  //这里保存所有比较花费的时间

      std::ofstream out("CompareAlogrithmAIResult.txt");//将结果保存在这里

     

      //在文件中输入第一行

      out <<"parameter" <<'/t';

      for(int i=0; i<pfAIVec.size(); ++i)

      {

         out <<"Algorithm " <<i+1 <<'/t';

      }

      out <<std::endl <<std::setprecision(4) <<std::scientific;

     

      double timeTaken;  //每个算法一次消耗的时间

 

      //以算法参数的数组个数为循环条件,每个数值让各个算法分别调用

      for(int i=0; i<vec.size(); ++i)

      {

         out <<vec[i] <<'/t';

         int *arr = new int[ vec[i] ];  //每次动态生成一个数组

         for(int j=0; j<pfAIVec.size(); ++j)

         {

           

            timeTaken = GetTime();

            pfAIVec[j](arr, vec[i]); //实际调用不同算法

            timeTaken = GetTime() - timeTaken;

            out <<timeTaken <<'/t';

         }

         delete []arr;   //删除arr,因为只考察算法的效率,所以根本不关心结果

                      //至于各算法是否正确由调用者保证

         out<<std::endl;

      }

      timeInAll = GetTime() - timeInAll;

      out <<"Compared time in all: " <<timeInAll <<std::endl;

   }

 

   void CompareAlgorithmI(const std::vector<pfI> &pfIVec,const std::vector<int>& vec)

   {

      double timeInAll = GetTime();  //这里保存所有比较花费的时间

      std::ofstream out("CompareAlogrithmIResult.txt");//将结果保存在这里

     

      //在文件中输入第一行

      out <<"parameter" <<'/t';

      for(int i=0; i<pfIVec.size(); ++i)

      {

         out <<"Algorithm " <<i+1 <<'/t';

      }

      out <<std::endl <<std::setprecision(4) <<std::scientific;

     

      double timeTaken;  //每个算法一次消耗的时间

 

      //以算法参数的数组个数为循环条件,每个数值让各个算法分别调用

      for(int i=0; i<vec.size(); ++i)

      {

         out <<vec[i] <<'/t';

         for(int j=0; j<pfIVec.size(); ++j)

         {

            timeTaken = GetTime();

            pfIVec[j](vec[i]); //实际调用不同算法

            timeTaken = GetTime() - timeTaken;

            out <<timeTaken <<'/t';

         }

         out<<std::endl;

      }

      timeInAll = GetTime() - timeInAll;

      out <<"Compared time in all: " <<timeInAll <<std::endl;

   }

}

 

 

rand.h

 

//-------Created By 九天雁翎(jtianling) Email:jtianling@gmail.com

//-------最后修改时间:.3.26

 

 

#ifndef RAND_H

#define RAND_H

 

namespace jtianling

{

   //还是需要自己设定种子,此函数只保证范围

   //此算法生成从lowBorderhighBorder的随机数,而且包括边界lowBorder,highBorder.

   //lowBorder=<n<=highBorder

   int RandIntInRange(int lowBorder, int highBorder);

 

   //算法描述如<<Data Structures and Algorithm Analysis in C++>>

   //By Mark Allen Weiss 题目.8算法所示,根据习惯,不对outArray[]的大小做任何检验,

   //调用此函数的人应该确保这一点,outArray的大小大于等于numOfArray

   //此算法的用途是高效地产生一个不重复的随机序列

   //且此序列正好包括(1,numOfArray)中所有自然数

   void RandArrayNoRepeatInN(int outArray[], int numOfArray);

 

   //此算法产生随机的不重复的数组,数组大小为N

   //利用set容器的特性来保证没有重复,因为set容器的查找远快于一个一个查找

   //所以此方法比<<Data Structures and Algorithm Analysis in C++>>

   //By Mark Allen Weiss 题目.8算法所示算法快,而且增长慢很多

   void RandArrayNoRepeat(int outArray[], int numOfArray);

 

   //产生一个的随机序列且此序列的数值只在(1,numOfArray)

   void RandArrayInN(int outArray[], int numOfArray);

 

   //产生一个随机的序列,且序列的值为完全随机,序列的大小由numOfArray指定

   void RandArray(int outArray[], int numOfArray);

 

}//end of namespace jtianling

 

 

 

rand.cpp

 

//-------Created By 九天雁翎(jtianling) Email:jtianling@gmail.com

//-------最后修改时间:.3.28

#include "rand.h"

#include <cstdlib>

#include <ctime>

#include <algorithm>

#include <set>

 

namespace jtianling

{

   //此算法生成从ij的随机数,而且包括边界i,j.i=<n<=j

   int RandIntInRange(int i, int j)

   {

         //确保i<j,不然就交换

      if(i > j)

      {

         int temp = i;

         i = j;

         j = temp;

      }

      //确保范围正确

      return rand()%(j-i+1) + i;

   }

 

 

   //算法描述如<<Data Structures and Algorithm Analysis in C++>>

   //By Mark Allen Weiss 题目.8算法所示,根据习惯,不对arr[]的大小做任何检验,

   //调用此函数的人应该确保这一点,arr的大小大于等于n

   //此算法的用途是高效地产生一个不重复的随机序列

   //且此序列正好包括(1,n)中所有自然数

   void RandArrayNoRepeatInN(int arr[], int n)

   {

      srand(time(NULL) );

      for(int i=0; i<n; ++i)

      {

         arr[i] = i + 1;

      }

      for(int i=0; i<n; ++i)

      {

         std::swap(arr[i], arr[RandIntInRange(0, i)] );

      }

   }

 

   //此算法产生随机的不重复的数组,数组大小为N

   //利用set容器的特性来保证没有重复,因为set容器的查找远快于一个一个查找

   //所以此方法比<<Data Structures and Algorithm Analysis in C++>>

   //By Mark Allen Weiss 题目.8算法所示算法快,而且增长慢很多

   void RandArrayNoRepeat(int arr[], int n)

   {

      srand(time(NULL) );

 

 

      std::set<int> intSet;

      int temp;

      for(int i=0; i<n; ++i)

      {

 

         while(true)

         {

            temp = rand();

            if(!intSet.count(temp))

            {

                arr[i] = temp;

                intSet.insert(temp);

                break;

            }

         }

      }

      PrintCon(arr, arr+n);

 

   }

 

   //产生一个的随机序列且此序列的数值只在(1,n),序列的大小由n指定

   void RandArrayInN(int arr[], int n)

   {

      srand(time(NULL) );

      for(int i=0; i<n; ++i)

      {

         arr[i] = RandIntInRange(0, n);

      }

   }

 

   //产生一个随机的序列,且序列的值为完全随机,序列的大小由n指定

   void RandArray(int arr[], int n)

   {

      srand(time(NULL) );

      for(int i=0; i<n; ++i)

      {

         arr[i] = rand();

      }

   }

 

 

}//end of namespace jtianling

 

 

 

分类:  我的程序 
标签: 

Posted By 九天雁翎 at 九天雁翎的博客 on 2007年07月06日

前一篇: 可恶的Cpp(c语言预处理器),windows.h,导致程序莫名错误 后一篇: 郁闷的要死,因为用中文注释,带来了无穷的痛苦