一、缺失值、随机采样、中位数(附源码)

时间:2021.9.30

目录

Puzzle 1:Find a missing value

Puzzle 2:Keep a random sample

快速排序

Puzzle 3:Keep a random sample

源代码:(只需要修改这几个参数即可)


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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值