Generate N different random numbers (C ++, range: 0 ~ N-1)
The project creation process usually involves a random selection process. This note mainly provides two methods to randomly generate N different random numbers, and then briefly introduces the main functions srand, rand and time in C ++. Finally, a simple example is provided. K images are randomly selected from a folder containing N images and saved to another folder.
I. method for generating N different random numbers
# Include
# Include
# Include
# Define N 20 # define K 10 void swap (int * a, int * B) {if (*! = * B) {// the location where two numbers are exchanged for an XOR operation * a ^ = * B; * B ^ = * a; * a ^ = * B ;}} /*************************************** **************************************** function Name: void generateDiffRandV1 (int a [], int n) * function: generate different random numbers * entry parameter: * return value: none * Backup note: change the time to space ************************************ **************************************** * **/void generateDiffRandV1 (int a [], int n, int k) {int I; time_t; for (I = 0; I <n; I ++) {a [I] = I ;} Srand (int) time (& t); for (I = 0; I <k; I ++) {swap (& a [I], & a [I + rand () % (n-I)]) ;}} /*************************************** **************************************** function Name: void generateDiffRandV2 (int a [], int n) * function: generate random numbers that are different from each other (the range of random numbers is 1 ~ N-1) * entry parameter: * return value: None ** thinking path: This is an array of seat numbers, which is then randomly extracted from the array. To prevent duplication, the system returns to zero immediately. *: Each time a landline number is generated, you only need to judge whether it is 0, which greatly improves the efficiency of program execution. **************************************** ***************************************/ Void generateDiffRandV2 (int a [], int n) {int * flag = (int *) malloc (sizeof (int) * n); static int flag_once = 0; int I, index; for (I = 0; I <n; I ++) flag [I] = I + 1; if (! Flag_once) {srand (time (0); flag_once = 1 ;}for (I = 0; I <n;) {index = rand () % n; if (flag [index]! = 0) {a [I ++] = flag [index]-1; flag [index] = 0 ;}} free (flag );} void printArray (int a [], int n) {int I; for (I = 0; I <n; I ++) {printf (% d, a [I]);} printf ();} int main () {int a [N]; generateDiffRandV1 (a, N, K); printArray (a, N ); generateDiffRandV2 (a, N); printArray (a, N); return 0 ;}
II. Introduction to srand, rand and time Functions
1: The srand function is the initialization function of the random number generator. It needs to provide a seed, which corresponds to a random number. If the same seed is used, the same random number will appear in the subsequent rand () function. For example: srand (1); Use 1 directly to initialize the seed. srand (1) is also the default seed. Included in the library .
For example:
# Include
# Include
Using namespace std; int main () {// srand is equivalent to the random number initialization function. It broadcasts the seed for the random number, // srand (unsigned) time (0 )); // time is returned for the time_t type srand (1); // time_t t = time (0); for (int I = 0; I <10; I ++) {cout <rand () <endl;} return 0 ;}
No matter how many times the code is run, it always generates a random number from seed 1, so the results are the same.
To avoid this problem, we use srand (unsigned) time (0); 0 indicates NULL, and time (NULL) indicates obtaining the current time, in this way, different random numbers can be generated every time a task is run. The result returned by time () is time_t, Which is forcibly converted to the unsigned type and included in the library. .
2: The rand function is a pseudo-random number generator. You must first call srand initialization. Generally, the random number seed is initialized with the current calendar time, so that different random numbers can be generated in each line of code. Also, the constant value RAND_MAX is two bytes and the size is 32767.
3. Example (K images are randomly selected from a folder containing N images and saved to another folder)
/* Randomly select 1 million different images from the image library */# include
# Include
// Srand function is used, so this header file # include
# Include BrowseDir. hpp # include
# Include
# Include
// The time function is used, so the header file using namespace std is used; # define N 20000 // the total number to be modified // randomly generate n different random numbers and save them in array a void generateDiffRandV2 (int a [], int n) {int * flag = (int *) malloc (sizeof (int) * n); static int flag_once = 0; int I, index; for (I = 0; I <n; I ++) flag [I] = I + 1; if (! Flag_once) {srand (time (0); // 0 indicates NULL, time (NULL) is to obtain the current time does not mean that the random number generated each time is the same as the previous flag_once = 1 ;}for (I = 0; I <n;) {index = rand () % n; if (flag [index]! = 0) {a [I ++] = flag [index]-1; flag [index] = 0 ;}} free (flag );} void printArray (int a [], int n) {int I; for (I = 0; I <n; I ++) {printf (% d, a [I]);} printf ();} void imgProcessing (const char * dir_path, const char * file_exts, int a [], int selectNum) {CStatDir stat_dir; stat_dir.SetInitDir (dir_path); stat_dir.BeginBrowse (file_exts); int indx = 0; sort (a, a + selectNum); // sorting function // printArray (a, selectNum ); int I = 0, j = 0; int count = 0; // counts the number of erroneous images for (vector
: Iterator iter = stat_dir.vec_files.begin (); iter! = Stat_dir.vec_files.end () & j <selectNum; iter ++) {if (I = a [j]) {// obtain the image storage path string img_file = * iter; string pre_img_save = img_file.substr (0, img_file.find_last_of (\) + _ 1 w; string img_save = pre_img_save + img_file.substr (img_file.find_last_of (\)); iplImage * img = cvLoadImage (* iter ). c_str (), 1); if (! Img) {cout <fail to load image <endl; count ++;} else {cout <a [j] <endl; cvSaveImage (img_save.c_str (), img);} j ++; I ++; cvReleaseImage (& img);} else I ++;} cout <the error img: <count <endl ;} int main () {int a [N]; generateDiffRandV2 (a, N); // printArray (a, 50); const char * img_dir = E: \ wang \ data \ image; // The path strength of the image must be changed to const char * file_exts = *. jpg | *. png; int selectNum = 10000; // The number of images to be selected needs to be changed imgProcessing (img_dir, file_exts, a, selectNum); return 0 ;}
Directory operation code BrowseDir. hpp:
# Pragma once # include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
Using namespace std; class CBrowseDir {protected: // absolute path for storing the initial directory, ending with '': char m_szInitDir [_ MAX_PATH]; public: // default constructor CBrowseDir (); // set the initial directory to dir. If false is returned, the directory cannot use bool SetInitDir (const char * dir ); // start to traverse files of the specified type by filespec in the initial directory and Its subdirectories. // wildcards can be used for filespec *?, The path cannot be included. // If false is returned, virtual bool BeginBrowse (const char * filespec) is aborted during the traversal process. protected: // traverses the Files specified by filespec in the dir directory. // For subdirectories, use the iterative method // if false is returned, it indicates that the bool BrowseDir (const char * dir, const char * filespec) file is aborted. // The BrowseDir function finds a file every time, call ProcessFile // and pass the file name as a parameter. // if false is returned, the file is aborted. // You can override this function, add your own processing code virtual bool ProcessFile (const char * filename); // The function BrowseDir enters each directory, call ProcessDir // and pass the directory name being processed and the upper-level directory name as parameters. // If The initial directory, parentdir = NULL // You can override this function, add your own processing code // For example, you can count the number of subdirectories here. virtual void ProcessDir (const char * currentdir, const char * parentdir);}; CBrowseDir: CBrowseDir () {// use the current directory to initialize m_szInitDirgetcwd (m_szInitDir, _ MAX_PATH); // if the last letter of the directory is not '', then add a ''int len = strlen (m_szInitDir); if (m_szInitDir [len-1]! = '\') Strcat (m_szInitDir, \);} bool CBrowseDir: SetInitDir (const char * dir) {// first convert dir to the absolute path if (_ fullpath (m_szInitDir, dir, _ MAX_PATH) = NULL) return false; // determine whether the directory contains if (_ chdir (m_szInitDir )! = 0) return false; // if the last letter in the directory is not '', add a ''int len = strlen (m_szInitDir) at the end; if (m_szInitDir [len-1]! = '\') Strcat (m_szInitDir, \); return true;} bool CBrowseDir: BeginBrowse (const char * filespec) {ProcessDir (m_szInitDir, NULL); return BrowseDir (m_szInitDir, filespec);} bool CBrowseDir: BrowseDir (const char * dir, const char * filespec) {_ chdir (dir); // first, find the long hFile that meets the requirements in the dir; _ finddata_t fileinfo; if (hFile = _ findfirst (filespec, & fileinfo ))! =-1) {do {// check whether the directory is correct. // if not, process if (! (Fileinfo. attrib & _ A_SUBDIR) {char filename [_ MAX_PATH]; strcpy (filename, dir); strcat (filename, fileinfo. name); // cout <filename <endl; if (! ProcessFile (filename) return false ;}while (_ findnext (hFile, & fileinfo) = 0); _ findclose (hFile );} // find the subdirectory in the dir. // because the ProcessFile of the derived class may change the current directory when processing the file in the dir, you must reset the current directory to dir. // After _ findfirst is executed, the system may have recorded the relevant information, so changing the directory // does not affect _ findnext. _ Chdir (dir); if (hFile = _ findfirst (*. *, & fileinfo ))! =-1) {do {// check whether it is a directory. // If yes, check whether it is a directory. or .. // if not, iterate if (fileinfo. attrib & _ A_SUBDIR) {if (strcmp (fileinfo. name ,.)! = 0 & strcmp (fileinfo. name ,..)! = 0) {char subdir [_ MAX_PATH]; strcpy (subdir, dir); strcat (subdir, fileinfo. name); strcat (subdir, \); ProcessDir (subdir, dir); if (! BrowseDir (subdir, filespec) return false ;}}while (_ findnext (hFile, & fileinfo) = 0); _ findclose (hFile);} return true ;} bool CBrowseDir: ProcessFile (const char * filename) {return true;} void CBrowseDir: ProcessDir (const char * currentdir, const char * parentdir) {}// a subclass derived from CBrowseDir, used to count the number of files and subdirectories in the Directory class CStatDir: public CBrowseDir {protected: int m_nFileCount; // The number of files saved int m_nSubdirCount; // Save the number of subdirectories public: vector
Vec_files; public: // default constructor CStatDir () {// initialize data members m_nFileCount and m_nSubdirCountm_nFileCount = m_nSubdirCount = 0;} // The number of returned files int GetFileCount () {return m_nFileCount;} // returns the number of subdirectories int GetSubdirCount () {// The ProcessDir function is also called when the initial directory is entered, // After the value is reduced by 1, the actual number of subdirectories is displayed. Return m_nSubdirCount-1;} void VisitedFiles (ostream & out) {for (vector
: Iterator iter = vec_files.begin (); iter! = Vec_files.end (); iter ++) {out <* iter <;}} virtual bool BeginBrowse (const char * filespec) {string file_exts = filespec; vector
Vec_exts; size_t pos_start = 0; size_t npos = file_exts.find (|); string exts; while (npos! = String: npos) {exts = file_exts.substr (pos_start, npos-pos_start); vec_exts.push_back (exts); pos_start = npos + 1; npos = file_exts.find (|, pos_start );} exts = file_exts.substr (pos_start); vec_exts.push_back (exts); bool sign = true; for (vector
: Iterator iter = vec_exts.begin (); iter! = Vec_exts.end (); iter ++) {exts = * iter; if (! CBrowseDir: BeginBrowse (exts. c_str () {sign = false ;}} return sign;} protected: // overwrite the ProcessFile function, which is called every time, add 1 virtual bool ProcessFile (const char * filename) {m_nFileCount ++; // cout <