时间:2021.9.30
目录
Puzzle 1:Find a missing value
简述算法过程:
已知a1--an,是不同的,且从1到n+1;
因此,将1到n逐个求和;
再减去全部的输入数据;
剩下的一个数字 ,即为缺失值。
实验代码:
// puzzle 1
int Solution1(Env& env) {
//env.s代表数据 起始的地方,文件1,1-10000
int sInt = stoi(env.s), sum = 0;
for (size_t i = (sInt - 1) * NumSize + 1; i != sInt * NumSize + 1; i++) {
//sum 减去的同时,加,共用一个for循环
sum = sum - env.get_data() + i;
}
cout << "缺失值:" << sum << endl;
}
实验结果(含时间、空间、输出结果):
Puzzle 2:Keep a random sample
简述算法过程:
取前K个数据,放入整数数组;
剩余的数据,每个对应一个随机数j,随机数j的范围为1到i,其中,i为该数据的序号;
如果随机数j<=i,则用该数据替代数组中j位置的元素。
使用快速排序,将抽样的数据数组排序。
实验代码:
// puzzle 2
int* Solution2(Env& env) {
//初始化数组,长度为 K
int* arr = new int[K]();
//取出表中 K 个数据 为数组元素 赋值
for (size_t i = 0; i != K; i++) {
arr[i] = env.get_data();
}
//初始化随机数种子
srand(time(NULL));
//遍历剩下的数据
//temp接受表格中的一个数据,若为 -1,则说明表格数据已经遍历完了
for (size_t i = K, temp = env.get_data(), j = 0; temp != -1; i++) {
//每个数据,对应一个随机数,范围,0 到 i-1 之间,
j = rand() % i;
//随机数 j 小于 k,则替换对应的数据
if (j < K) {
arr[j] = temp;
}
//获取下一个数据
temp = env.get_data();
}
//将数组中的元素 进行 排序,arr[0] 到 arr[K-1]排序
QuickSort(arr, 0, K - 1);
//algorithm头文件里的,标准库排序算法
//sort(arr, arr + K);
//输出数组中的元素
for (size_t i = 0; i != K; i++) {
//控制输出数据的格式
cout << "arr" << setw(2) << i << ":" << arr[i] << '\t';
if (i % 3 == 0) {
cout << endl;
}
}
return arr;
}
快速排序
//快速排序
void QuickSort(int* arr, int left, int right) {
//递归high <= low时递归结束
if (left >= right)
return;
int low = left, high = right, keyValue = arr[left];
//划分
while (low < high) {
//找一个小于key的,
while (arr[high] >= keyValue && low < high)
high--;
arr[low] = arr[high];
//找一个大于key的,
while (arr[low] <= keyValue && low < high)
low++;
arr[high] = arr[low];
}
//将key值赋给中间位置
arr[low] = keyValue;
//递归划分
QuickSort(arr, left, low - 1);
QuickSort(arr, low + 1, right);
}
实验结果(含时间、空间、输出结果):
Puzzle 3:Keep a random sample
简述算法过程:
简述算法过程:
将数组中随机取样的数据排序,然后取出中位数。
数组长度为偶数,则取最中间两个数据求平均,即为中位数。
数组长度为奇数,取取最中间的,即为中位数。
实验代码:
void Solution3(Env& env) {
int* arr = Solution2(env);
//输出中位数
int median = 0;
if (K % 2) {//奇数,则直接输出最中间的元素
median = arr[(K >> 1) + 1];
} else {//偶数,则将最中间的两个元素求和,取平均,然后输出
median = (arr[(K >> 1)] + arr[(K >> 1) + 1]) >> 1;
}
cout << "median : " << median << endl;
}
实验结果(含时间、空间、输出结果):
源代码:(只需要修改这几个参数即可)
实验数据链接:
#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <iomanip>
#include <algorithm>
using namespace std;
//FileNum为访问的文件数量,NumSize 为文件数据大小,K为均匀随机采样的数据数量,Puzzle为求解题目
const int FileNum = 5, NumSize = 10000, K = 10, Puzzle = 3;
class Env {
public:
int data[NumSize];
int pointer_max = 0;
int pointer = 0;
string s = "0";
Env(string str) {
s = str;
cout << "文件" << s << endl;
// rand_1.csv rand_2.csv rand_3.csv rand_4.csv rand_5.csv 共5个测试用例,请依次测试
ifstream file("test_data/rand_" + s + ".csv", ios::in);
if (!file.is_open())
cout << " 文件打开失败!" << endl;
string temp;
while (getline(file, temp)) {
data[pointer_max] = atoi(temp.c_str());
pointer_max++;
}
file.close();
}
int get_data() {
if (!done())
return data[pointer++];
else
return -1;
}
bool done() {
if (pointer < pointer_max)
return false;
else
return true;
}
};
//快速排序
void QuickSort(int* arr, int left, int right) {
//递归high <= low时递归结束
if (left >= right)
return;
int low = left, high = right, keyValue = arr[left];
//划分
while (low < high) {
//找一个小于key的,
while (arr[high] >= keyValue && low < high)
high--;
arr[low] = arr[high];
//找一个大于key的,
while (arr[low] <= keyValue && low < high)
low++;
arr[high] = arr[low];
}
//将key值赋给中间位置
arr[low] = keyValue;
//递归划分
QuickSort(arr, left, low - 1);
QuickSort(arr, low + 1, right);
}
// puzzle 1
int Solution1(Env& env) {
//env.s代表数据 起始的地方,文件1,1-10000
int sInt = stoi(env.s), sum = 0;
for (size_t i = (sInt - 1) * NumSize + 1; i != sInt * NumSize + 1; i++) {
//sum 减去的同时,加,共用一个for循环
sum = sum - env.get_data() + i;
}
cout << "缺失值:" << sum << endl;
}
// puzzle 2
int* Solution2(Env& env) {
//初始化数组,长度为 K
int* arr = new int[K]();
//取出表中 K 个数据 为数组元素 赋值
for (size_t i = 0; i != K; i++) {
arr[i] = env.get_data();
}
//初始化随机数种子
srand(time(NULL));
//遍历剩下的数据
//temp接受表格中的一个数据,若为 -1,则说明表格数据已经遍历完了
for (size_t i = K, temp = env.get_data(), j = 0; temp != -1; i++) {
//每个数据,对应一个随机数,范围,0 到 i-1 之间,
j = rand() % i;
//随机数 j 小于 k,则替换对应的数据
if (j < K) {
arr[j] = temp;
}
//获取下一个数据
temp = env.get_data();
}
//将数组中的元素 进行 排序,arr[0] 到 arr[K-1]排序
QuickSort(arr, 0, K - 1);
//algorithm头文件里的,标准库排序算法
//sort(arr, arr + K);
//输出数组中的元素
for (size_t i = 0; i != K; i++) {
//控制输出数据的格式
cout << "arr" << setw(2) << i << ":" << arr[i] << '\t';
if (i % 3 == 0) {
cout << endl;
}
}
return arr;
}
void Solution3(Env& env) {
int* arr = Solution2(env);
//输出中位数
int median = 0;
if (K % 2) {//奇数,则直接输出最中间的元素
median = arr[(K >> 1) + 1];
} else {//偶数,则将最中间的两个元素求和,取平均,然后输出
median = (arr[(K >> 1)] + arr[(K >> 1) + 1]) >> 1;
}
cout << "median : " << median << endl;
}
// 所有的代码都需要写在 Algo 类内,自行定义其他需要的变量或函数
class Algo {
public:
Algo() {
cout << "algo ok" << endl;
}
int run(Env& env) {
if (Puzzle == 1)
Solution1(env);
else if (Puzzle == 2)
Solution2(env);
else if (Puzzle == 3)
Solution3(env);
//cout<<endl;
}
};
int main() {
Env* env;
for (int i = 1; i != FileNum + 1; i++) {
env = new Env(to_string(i));
Algo algo;
time_t start = clock();
algo.run(*env);
time_t end = clock();
cout << "程序耗时: " << double(end - start) / CLOCKS_PER_SEC << " ms" << endl;
cout << "占用内存:" << sizeof(algo) << " byte" << endl;
delete env;
cout << endl;
}
system("pause");
return 0;
}