測試數據之自動生成


最近在學習排序算法的時候,需要利用程序自動生成測試數據,代碼和思路整理在這篇文章里面。

文章圖片來源於 GitHub,網速不佳的朋友請點我看原文

順便軟廣一下個人技術小站:https://godbmw.com。歡迎常來 ♪(^∇^*)

1. 設計思路

因為會被很多排序算法調用,所以,數據自動生成代碼應該放在.h頭文件中。為了防止命名沖突,函數被封裝在“命名空間”中(代碼中命名空間是: SortTestHelper)。

而對於排序來說,自動生成數據的類型需要有以下幾種:

  1. [a, b]范圍內的n個隨機數據,比如:1、2、100、-1...
  2. n個近乎有序的數據,比如:1、2、3、7、5、6、4...
  3. n個近乎相同的數據,比如:1、1、1、2、2、2、2、2...

除此之外,還需要數組淺拷貝、打印的函數,以及驗證是否排序成功和測試排序時間的函數。

2. 用的知識點

  1. srand(time(NULL))rand() : 設立隨機種子,生成隨機數
  2. clock() : 用來算法運行前后的計算時鍾周期差值,再除以CLOCKS_PER_SEC 即為運行秒數。
  3. 函數式編程 : 使用函數指針,方便調用和測試排序函數

其中rand()函數能生成 0 到MAX_INT之間的隨機整數。如果想生成[0, n)之間的整數,需要取余操作:int x = rand() % n;;如果想生成[left, right]之間的整數,需要進行偏移:int x = rand() % (right - left + 1) + left;

3. 代碼實現

//
// Created by GodBMW.com on 2018/9/11.
//

#ifndef BASESORT_SORTHELPER_H
#define BASESORT_SORTHELPER_H

#include <iostream>
#include <string>
#include <ctime>
#include <cassert>

using namespace std;

namespace SortTestHelper {
    // 生成[left, right]范圍內n個隨機數
    template <typename T>
    T* generateRandomArray(int n, int left, int right) {
        assert( left <= right );
        T *arr = new T[n];
        srand(time(NULL)); // set random seed
        for(int i = 0; i < n; i++) {
            arr[i] = rand() % (right - left + 1) + left;
        }
        return arr;
    }

    // 生成[0, n)范圍內n個近乎有序的隨機數
    template <typename T>
    T* generateNearlyOrderedArray(int n, int swap_times) {
        T *arr = new T[n];
        srand(time(NULL));
        // 先生成長度為n的有序數組
        for(int i = 0; i < n; i++) {
            arr[i] = i + 1;
        }
        // 隨機選取其中2個數據,交換 swap_times 次
        for(int i = 0; i < swap_times; i++) {
            int pos_x = rand() % n;
            int pos_y = rand() % n;
            swap(arr[pos_x], arr[pos_y]);
        }
        return arr;
    }

    template <typename T>
    T* copyArray(T arr[], int length) {
      T* brr = new T[length]; // 注意檢查brr數組大小
      copy(arr, arr + length, brr);
      return brr;
    }

    template <typename T>
    void printArray(T arr[], int length) {
        for(int i = 0; i < length; i++) {
            cout<< arr[i] << " ";
        }
        cout<< endl;
        return;
    }

    template <typename T>
    bool isSorted(T arr[], int length) {
        for(int i = 0; i < length-1; i++) {
            if(arr[i] > arr[i + 1]) {
                return false;
            }
        }
        return true;
    }

    // 第三個參數是函數指針,傳入后,可以在本函數內運行被傳入的函數
    template <typename T>
    void testSort(T arr[], int length, void(*sort)(T[], int), string name) {
        clock_t startTime = clock();
        sort(arr, length);
        clock_t endTime = clock();

        assert(isSorted(arr, length));
        cout << name << " : " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
        // endTime - startTime: 時鍾周期
        return;
    }

}

#endif //BASESORT_SORTHELPER_H

我們沒有實現第二部分所說的 生成n個近乎相同的數據,比如:1、1、1、2、2、2、2、2...。因為可以借助 generateRandomArray 函數,比如:SortTestHelper::generateRandomArray(10000, 0, 10)。生成[0,10]區間內 10000 個整數,那么不就是近乎相同的嗎?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM