zoukankan      html  css  js  c++  java
  • 数据处理程序

    前段时间帮一个外学院的老师处理数据,发现自己会的太少的,按理用脚本应该可以更方便搞定的(没研究那么深),结果硬是写了400行的C++代码。

    IDE 用的是CodeBlocks

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <windows.h>
    #include <stdio.h>
    #include <string.h>
    #define LEN 1024
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e6 + 10;
    const int INF = 1e9 + 7;
    struct Data {
        int number; // 区站号
        int year; // 年
        int month; // 月
        int day; // 日
        double water; // 20-20时降水量
        double Max; // 日最高气温
        double Min; // 日最低气温
        double aver; // 平均气温
    };
    Data num[MAXN];
    bool cmp(Data a, Data b) {
        if(a.year != b.year) {
            return a.year < b.year;
        }
        else {
            return a.month != b.month ? a.month < b.month : a.day < b.day;
        }
    }
    //输出结果:
    //年份	一般性高温(35 ℃ - 38 ℃)天	危害性高温(38 ℃ - 40 ℃)天
    //强危害性高温(≥ 40 ℃)天	极端最高气温(各台站每一年日高温最大值)℃
    //热浪日数	最长热浪持续日数
    struct Answer {
        int year; // 年份
        int num1; // 一般性高温(35 ℃ - 38 ℃)天
        int num2; // 危害性高温(38 ℃ - 40 ℃)天
        int num3; // 强危害性高温(≥ 40 ℃)天
        double Max; // 极端最高气温(各台站每一年日高温最大值)℃
        int day1; // 热浪日数
        int day2; // 最长热浪持续日数
    };
    Answer ans[MAXN];
    
    double rec[MAXN]; // 存储1961 - 1990的所有日最高温度
    
    int D[13] = {0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    bool judge(int y) {
        return y % 400 == 0 || (y % 4 == 0 && y % 100);
    }
    
    void Work1(LPCSTR FullPathName, LPCSTR outputPath1) {
        freopen(FullPathName, "r", stdin);
        freopen(outputPath1, "w", stdout);
        char str[1000];
        for(int i = 1; i <= 8; i++) {
            scanf("%s", str);
        }
        int N = 0; int M = 0;
        int res = 0;
        while(scanf("%d%d%d%d%lf%lf%lf%lf", &num[N].number, &num[N].year, &num[N].month, &num[N].day,
                      &num[N].water, &num[N].Max, &num[N].Min, &num[N].aver) != EOF) {
            if(num[N].year >= 1961 && num[N].year <= 1990) {
                rec[M++] = num[N].Max;
            }
            N++;
        }
        //如果输入的数据 没有按年月日严格排列
        sort(num, num + N, cmp);
    
        //判断1961-2016的数据全不全
        int s = -1;
        for(int i = 0; i < N; i++) {
            if(num[i].year == 1961) {
                s = i; break;
            }
        }
        if(s == -1) {
            printf("1961-2015年数据不全
    ");
            return ;
        }
        bool flag = true;
        for(int i = 1961; i <= 2015; i++) {
            if(judge(i)) {
                D[2] = 29;
            }
            else {
                D[2] = 28;
            }
            for(int j = 1; j <= 12; j++) {
                for(int k = 1; k <= D[j]; k++) {
                    if(s < N && num[s].year == i && num[s].month == j && num[s].day == k) {
                        s++;
                    }
                    else {
                        printf("%d %d %d
    ", i, j, k);
                        flag = false; break;
                    }
                }
                if(!flag) break;
            }
            if(!flag) break;
        }
        if(num[N - 1].year == 2015 && num[N - 1].month == 12 && num[N - 1].day == 31) {
    
        }
        else {
            flag = false;
        }
        if(!flag) {
            printf("1961-2015年数据不全
    ");
            return ;
        }
    
        // 处理缺测数据
        for(int i = 0; i < N; i++) {
            if(num[i].Max >= 30000) {
                num[i].Max = 0;
            }
        }
        int j = 0; // 从1961年开始
        for(int i = 0; i < N; i++) {
            if(num[i].year == 1961) {
                j = i; break;
            }
        }
        for(int i = 1961; i <= 2015; i++) {
            ans[i].year = i;
            ans[i].num1 = 0; ans[i].num2 = 0; ans[i].num3 = 0;
            ans[i].Max = -100000000;
            for(; j < N; j++) {
                if(num[j].year != i) break;
    
                ans[i].Max = max(ans[i].Max, num[j].Max); // 求解每年极端最高气温
    
                if(num[j].Max >= 350 && num[j].Max < 380) {
                    ans[i].num1++;
                } // 求解一般性高温(35 ℃ - 38 ℃)天
    
                if(num[j].Max >= 380 && num[j].Max < 400) {
                    ans[i].num2++;
                } // 求解危害性高温(38 ℃ - 40 ℃)天
    
                if(num[j].Max >= 400) {
                    ans[i].num3++;
                } // 求解强危害性高温(≥ 40 ℃)天
    
            }
        }
        double mark = 320; // 热浪的临界温度值
        //求解热浪的临界温度值
        sort(rec, rec + M); // 升序排列
        //找第95百分位 温度值
        if((M * 95) % 100 == 0) {
            mark = max(mark, 1.0 * rec[(M * 95) / 100 - 1]);
        }
        else {
            int pos = (M * 95) / 100 - 1;
            mark = max(mark, 1.0 * (rec[pos] + rec[pos + 1]) / 2);
        } // 取平均值
    
        j = 0;
        for(int i = 0; i < N; i++) {
            if(num[i].year == 1961) {//从1961年
                j = i; break;
            }
        }
        for(int i = 1961; i <= 2015; i++) {
            ans[i].day1 = 0; ans[i].day2 = 0;
            int s = -1; // 记录热浪的起始点
            for(; j < N; j++) {
                if(num[j].year != i) break;
                if(num[j].Max >= mark) {
                    if(s == -1) { // 未设置起点
                        s = j;
                    }
                }
                else { // 断了
                    if(s != -1) { // 是否存在起点
                        int cnt = j - s; // 持续天数
                        if(cnt >= 3) { // 超过三天
                            ans[i].day1 += cnt;
                            ans[i].day2 = max(ans[i].day2, cnt);
                        }
                    }
                    s = -1;
                }
            }
            if(s != -1) {
                int cnt = j - s;
                if(cnt >= 3) {
                    ans[i].day1 += cnt;
                    ans[i].day2 = max(ans[i].day2, cnt);
                }
            }
        }
        printf("年份    ");
        printf(" 一般性高温(35℃-38℃)天    ");
        printf(" 危害性高温(38℃-40℃)天    ");
        printf("强危害性高温(≥40℃)天   ");
        printf(" 极端最高气温(各台站每一年日高温最大值)℃");
        printf("     热浪日数          ");
        printf(" 最长热浪持续日数
    ");
    
        for(int i = 1961; i <= 2015; i++) {
            printf("%-1d                       ", ans[i].year);
            printf("%-1d                         ", ans[i].num1);
            printf("%-1d                         ", ans[i].num2);
            printf("  %-1d                         ", ans[i].num3);
            printf("     %-1.0lf                      ", ans[i].Max);
            printf("        %-1d                        ", ans[i].day1);
            printf("%-1d                         
    ", ans[i].day2);
        }
    
        //1961 - 1990 均值
        printf("1961-1990均值              ");
        double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, sum6 = 0;
        for(int i = 1961; i <= 1990; i++) {
            sum1 += ans[i].num1;
            sum2 += ans[i].num2;
            sum3 += ans[i].num3;
            sum4 += ans[i].Max;
            sum5 += ans[i].day1;
            sum6 += ans[i].day2;
        }
        printf("%-1.2lf                      ", sum1 / 30);
        printf("%-1.2lf                      ", sum2 / 30);
        printf("  %-1.2lf                      ", sum3 / 30);
        printf("     %-1.2lf                   ", sum4 / 30);
        printf("        %-1.2lf                      ", sum5 / 30);
        printf("%-1.2lf                       
    ", sum6 / 30);
    
        //1991 - 2015 均值
        printf("1991-2015均值              ");
        sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, sum6 = 0;
        for(int i = 1991; i <= 2015; i++) {
            sum1 += ans[i].num1;
            sum2 += ans[i].num2;
            sum3 += ans[i].num3;
            sum4 += ans[i].Max;
            sum5 += ans[i].day1;
            sum6 += ans[i].day2;
        }
        printf("%-1.2lf                      ", sum1 / 25);
        printf("%-1.2lf                      ", sum2 / 25);
        printf("  %-1.2lf                      ", sum3 / 25);
        printf("     %-1.2lf                   ", sum4 / 25);
        printf("        %-1.2lf                      ", sum5 / 25);
        printf("%-1.2lf                       
    ", sum6 / 25);
    }
    
    char outputPath2[LEN]; // 每个省输出文件的路径
    void Work2_Init() { // 用于Work2
        // 求出 均值数据输出路径
        //strcpy(outputPath2, "C:\Users\chenzhenyu\Desktop\Newdata\重庆市\均值.txt");
        freopen("out.txt", "a", stdout);
        printf("区站号    ");
        printf("第一阶段   ");
        printf(" 一般性高温(35℃-38℃)天    ");
        printf(" 危害性高温(38℃-40℃)天    ");
        printf("强危害性高温(≥40℃)天   ");
        printf(" 极端最高气温(各台站每一年日高温最大值)℃");
        printf("     热浪日数          ");
        printf(" 最长热浪持续日数        ");
    
        printf("第二阶段   ");
        printf(" 一般性高温(35℃-38℃)天    ");
        printf(" 危害性高温(38℃-40℃)天    ");
        printf("强危害性高温(≥40℃)天   ");
        printf(" 极端最高气温(各台站每一年日高温最大值)℃");
        printf("     热浪日数          ");
        printf(" 最长热浪持续日数
    ");
    }
    
    void Work2(LPCSTR FullPathName, char *s) {
        freopen(FullPathName, "r", stdin);
        freopen("out.txt", "a", stdout);
        char ss[1000]; scanf("%s", ss);
        bool First = false;
        if(ss[0] >= '0' && ss[0] <= '9') {
            First = true;
        }
        for(int i = 2; i <= 7; i++) {
            scanf("%s", ss);
        }
        if(First) {
            for(int i = 1962; i <= 2015; i++) {
                for(int j = 1; j <= 7; j++) {
                    scanf("%s", ss);
                }
            }
        }
        else {
            for(int i = 1961; i <= 2015; i++) {
                for(int j = 1; j <= 7; j++) {
                    scanf("%s", ss);
                }
            }
        }
        printf("%s    ", s);
        for(int i = 1; i <= 2; i++) {
            for(int j = 1; j <= 7; j++) {
                scanf("%s", ss);
                printf("%s           ", ss);
            }
        }
    
        printf("
    ");
    }
    void Work3(LPCSTR Path, char *s) { // 筛选区站号为s的最新年份的站点数据,路径为Path
        freopen("安徽.txt", "r", stdin); // 打开该省最新年份所有站点的数据文件
        freopen(Path, "a", stdout);
        char str[100];
        for(int i = 1; i <= 20; i++) {
            scanf("%s", str);
        }
        int val = 0;
        for(int i = 0; i < 5; i++) {
            val = val * 10 + s[i] - '0';
        }
        int a[30];
        while(scanf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
            &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9], &a[10],
        &a[11], &a[12], &a[13], &a[14], &a[15], &a[16], &a[17], &a[18], &a[19], &a[20]) != EOF) {
            if(a[1] == val) {
                printf("%d %d %d %d %d %d %d
    ", a[1], a[2], a[3], a[4], a[20], a[15], a[16], a[14]);
            }
        }
    
    }
    BOOL DirectoryList(LPCSTR Path) {
        WIN32_FIND_DATA FindData;
        HANDLE hError;
        char FilePathName[LEN];
        // 构造路径
        char FullPathName[LEN];
        strcpy(FilePathName, Path);
        strcat(FilePathName, "\*.*");
        hError = FindFirstFile(FilePathName, &FindData);
        if (hError == INVALID_HANDLE_VALUE) {
            printf("搜索失败!");
            return 0;
        }
        while(::FindNextFile(hError, &FindData)) {
            // 过虑.和..
            if (strcmp(FindData.cFileName, ".") == 0
                || strcmp(FindData.cFileName, "..") == 0 ) {
                continue;
            }
            // 构造完整路径
            sprintf(FullPathName, "%s\%s", Path, FindData.cFileName);
            /*
            // 用于Work1,求出每个站每一年的数据
            char outputPath1[LEN]; // Work1中输出文件的路径
            strcpy(outputPath1, "C:\Users\chenzhenyu\Desktop\Newdata\安徽省\out");
            strcat(outputPath1, "\");
            strcat(outputPath1, FindData.cFileName);
            Work1(FullPathName, outputPath1); // 统计所有基础信息
            */
    
            bool Stop = false;
    
            int len = strlen(FullPathName);
            if(FullPathName[len - 1] != 't') {
                Stop = true;
            }
            if(!(FullPathName[len - 5] >= 0 && FullPathName[len - 5] <= '9')) {
                Stop = true;
            }
            if(FullPathName[len - 11] != 't') {
                Stop = true;
            }
            // 求出区站号
            char number[1000];
            for(int i = 0; i <= 4; i++) {
                number[i] = FindData.cFileName[i];
            }
            number[5] = 0;
    
            if(!Stop) {
                //cout << FullPathName << endl;
                Work2(FullPathName, number); // 统计均值
            }
    
            //Work3(FullPathName, number); // 筛选区站号为number路径为FullPathName的数据
    
            if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                DirectoryList(FullPathName);
            }
        }
        return 0;
    }
    
    int main()
    {
        //Work2_Init(); // 用于统计每个省 两个阶段的数据
        DirectoryList("C:\Users\chenzhenyu\Desktop\Newdata");
        /*
        李震需要的的部分
        */
        /*for(int i = 1961; i <= 2016; i++) {
            //freopen("每年所有站点数据平均值.txt", "a", stdout);
            DirectoryList("C:\Users\chenzhenyu\Desktop\Newdata\安徽省");
        }*/
        return 0;
    }
    
    
    
  • 相关阅读:
    利用Python和webhook实现自动提交代码
    Python threading 单线程 timer重复调用函数
    Python requests 使用心得
    openresty实现接口签名安全认证
    使用jedis面临的非线程安全问题
    记一次线上升级openresty中kafka版本产生的多版本兼容问题
    mysql中走与不走索引的情况汇集(待全量实验)
    Elasticsearch深分页以及排序查询问题
    IO多路复用:Redis中经典的Reactor设计模式
    Netty在Dubbo中的使用过程源码分析
  • 原文地址:https://www.cnblogs.com/Czhenyu/p/6443828.html
Copyright © 2011-2022 走看看