数据处理程序

前段时间帮一个外学院的老师处理数据,发现自己会的太少的,按理用脚本应该可以更方便搞定的(没研究那么深),结果硬是写了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年数据不全\n");
        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\n", 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年数据不全\n");
        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(" 最长热浪持续日数\n");

    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                         \n", 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                       \n", 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                       \n", 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(" 最长热浪持续日数\n");
}

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("\n");
}
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\n", 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;
}


posted @ 2017-02-26 11:07  笑着走完自己的路  阅读(276)  评论(0编辑  收藏  举报