如何在一个C++程序中实现多个独立的随机数生成器?
问题解决:独立随机数生成与排序代码修正
问题分析
你当前的核心问题是多次调用srand(std::time(0))导致随机数种子重复——程序运行速度远快于秒级时间更新,多次调用时time(0)返回相同值,使得rand()生成完全一致的随机序列。此外原代码存在逻辑错误:在输出循环里反复调用排序函数,导致数组被重复排序,完全没必要。
解决方案
方案1:单次初始化全局种子,连续生成不同数组的随机数
只在程序开头调用一次srand(),之后所有数组的随机数从同一个全局序列中连续获取,每个数组的随机数自然不同。
方案2:实现独立的随机数生成器(不依赖全局rand)
如果需要完全独立的随机序列,可以自己实现线性同余生成器(LCG),每个生成器维护自身状态,互不干扰。
以下是采用方案1的修正代码,同时修复排序调用的逻辑错误:
修改后的代码
main.cpp
#include <iostream> #include <cstdlib> #include <ctime> #include "AssortedSorter.h" using namespace std; int main() { AssortedSorter sorter; int UserNumOfNumbers; int bchoice; // 只初始化一次随机数种子,放在程序开头 srand(std::time(0)); cout << "我们选数组大小(0) 还是你选(1): "; cin >> bchoice; if (bchoice == 0) { UserNumOfNumbers = 10000; // 生成原始随机数组 int array[UserNumOfNumbers]; for (int i = 0; i < UserNumOfNumbers; i++) { array[i] = (rand() % 200002) + 1; } // 冒泡排序演示 cout << "\n冒泡排序结果::" << endl; int bubbleArray[UserNumOfNumbers]; for (int i = 0; i < UserNumOfNumbers; i++) { bubbleArray[i] = array[i]; } sorter.bubbleSort(bubbleArray, UserNumOfNumbers); // 只输出前10个元素避免刷屏 for (int i = 0; i < 10; i++) { cout << "第" << i + 1 << "个元素::" << bubbleArray[i] << endl; } // 快速排序演示 cout << "\n快速排序结果::" << endl; int quickArray[UserNumOfNumbers]; for (int i = 0; i < UserNumOfNumbers; i++) { quickArray[i] = array[i]; } // 修正stop参数:原代码传入数组长度会越界,改为长度-1 sorter.quicksort(quickArray, 0, UserNumOfNumbers - 1); for (int i = 0; i < 10; i++) { cout << "第" << i + 1 << "个元素::" << quickArray[i] << endl; } } else if (bchoice == 1) { cout << "输入10到20000之间的数字: "; cin >> UserNumOfNumbers; while (UserNumOfNumbers < 10 || UserNumOfNumbers > 20000) { cout << "输入无效! 请重新输入: "; cin >> UserNumOfNumbers; } // 生成冒泡排序用数组 int bubbleArray[UserNumOfNumbers]; for (int i = 0; i < UserNumOfNumbers; i++) { bubbleArray[i] = (rand() % 200002) + 1; } cout << "\n冒泡排序结果::" << endl; sorter.bubbleSort(bubbleArray, UserNumOfNumbers); for (int i = 0; i < 10; i++) { cout << "第" << i + 1 << "个元素::" << bubbleArray[i] << endl; } // 生成快速排序用数组,从全局序列继续获取随机数,自然不同 int quickArray[UserNumOfNumbers]; for (int j = 0; j < UserNumOfNumbers; j++) { quickArray[j] = (rand() % 200002) + 1; } cout << "\n快速排序结果::" << endl; sorter.quicksort(quickArray, 0, UserNumOfNumbers - 1); for (int j = 0; j < 10; j++) { cout << "第" << j + 1 << "个元素::" << quickArray[j] << endl; } } return 0; }
AssortedSorter.cpp
#include <iostream> #include "AssortedSorter.h" using namespace std; int AssortedSorter::partition(int array[], int start, int stop) { int up = start, down = stop - 1, part = array[stop]; if (stop <= start) return start; while (true) { while (array[up] < part) { up++; } while ((part < array[down]) && (up < down)) { down--; } if (up >= down) break; swap(array[up], array[down]); up++; down--; } swap(array[up], array[stop]); return up; } int AssortedSorter::getquicksort() const { return *b; } void AssortedSorter::quicksort(int a[], int start, int stop) { int i, s = 0, stack[20001]; stack[s++] = start; stack[s++] = stop; while (s > 0) { stop = stack[--s]; start = stack[--s]; if (start >= stop) continue; i = partition(a, start, stop); if (i - start > stop - i) { stack[s++] = start; stack[s++] = i - 1; stack[s++] = i + 1; stack[s++] = stop; } else { stack[s++] = i + 1; stack[s++] = stop; stack[s++] = start; stack[s++] = i - 1; } } } void AssortedSorter::bubbleSort(int array[], int size) { int maxElement; int index; for (maxElement = size - 1; maxElement > 0; maxElement--) { for (index = 0; index < maxElement; index++) { if (array[index] > array[index + 1]) { swap(array[index], array[index + 1]); } } } } void AssortedSorter::selectionSort(int array[], int size) { int minIndex, minValue; for (int start = 0; start < (size - 1); start++) { minIndex = start; minValue = array[start]; for (int index = start + 1; index < size; index++) { if (array[index] < minValue) { minValue = array[index]; minIndex = index; } } swap(array[minIndex], array[start]); } } void AssortedSorter::swap(int &a, int &b) { int temp = a; a = b; b = temp; }
AssortedSorter.h
#ifndef SORTER_ASSORTEDSORTER_H #define SORTER_ASSORTEDSORTER_H class AssortedSorter { public: void quicksort(int a[], int, int); int getquicksort() const; int partition(int [], int, int); void bubbleSort(int[], int); int getbubblesort() const; int getswap() const; void selectionSort(int[], int); void swap(int &, int &); private: int* b; }; #endif //SORTER_ASSORTEDSORTER_H
关键修正点
- 随机数种子初始化:仅在程序开头调用一次
srand(time(0)),避免重复初始化导致种子相同。 - 排序逻辑修正:将"输出循环中反复排序"改为"先排序整个数组,再输出结果",大幅提升效率。
- 数组复制:为每个排序算法单独复制原数组,避免排序后修改原数组影响其他算法。
- 快速排序参数修正:原代码传入数组长度作为
stop参数会导致越界,修正为数组长度-1。
如果需要完全独立的随机数生成器(比如并行场景),可以实现自定义线性同余生成器:
// 独立随机数生成器 class RandomGenerator { private: unsigned int seed; public: RandomGenerator(unsigned int s) : seed(s) {} int next() { // 经典LCG参数 seed = seed * 1103515245 + 12345; return (unsigned int)(seed / 65536) % 200002 + 1; } }; // 使用示例 RandomGenerator gen1(time(0)); RandomGenerator gen2(time(0) + 1234); // 不同种子保证独立序列
内容的提问来源于stack exchange,提问作者autoMATE
相关产品推荐
相关产品推荐

