给某位同学的 按照窗口(每个窗口涵盖50个数据,窗口每10个数据步进一次)求标准差,平均值, (样本值-平均值)/标准差的程序

这段代码实现了一个程序,用于读取包含浮点数的文本文件,按照每50个数据为一个窗口,步进10个数据的方式,计算每个窗口内的数据标准差、平均值,并进行Z-Score标准化。程序首先读取文件,然后对数据进行处理,最终将结果写入到不同的输出文件中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
//#inlcude <stdlib.h>
using namespace std;

#define FILENAME "txt_excel2.txt.iso"
#define FILEOUT "result_out.txt.iso"
#define FILEOUT2 "result_out2.txt.iso"

#define WIN_DATAIN "win_datain.txt.iso"

#define FILE_AVER "averige.txt.iso"
#define FILE_BZC "std_deviation.txt.iso"

 

double sum_d(double *buf, int len);
double averagex(double sum, int len);
double variance(double* data_in, double aver, int len);


int writefile(const char *file, double *datain, int len, int opt);
void del_zero(char * buf);

 


int atof_x(char *buf, double* f)
{
    double x;
    //cout<<" ++" <<buf<< "++ ";
    if(!strncmp("end", buf, 3))
    {
        return -3;//列内容结束
    }
    if((buf[0]!='-')&&(buf[0]!='+')&&((buf[0]<'0')||(buf[0]>'9')))
    {
        return -1;//不是浮点数;
    }
    for(int i = 1 ; i < strlen(buf); ++i)
    {
        if((buf[i]!='.')&&(buf[i]<'0')||(buf[i]>'9'))
            return -2;//不是浮点数;        
    }
    x = atof(buf);
   
    //cout << " {"<< x << "} " ;
    *f = x;
    return 0;
}

void print_double(double *buf, int len)
{
    int i=0;
    if(!buf)
        return ;
    while(i!=len)
    {
        if(!(i%10))
            cout <<endl;
        cout << buf[i] << " ";
        i++;
    }   
    cout<< endl;
}

double f_buf[990000] = {0};
double s_all[900000] = {0};
double aver_all[900000] = {0};
double o_buf[5*990000] = {0};

double windatain_buf[5*990000] = {0};


int main(void)
{
    char buffer[256];
    fstream out;
   
    int step = 10;
    int last = 0;
    int count_step = 0;
    int count_result =0;
    char file_in[512];
   
    int n = 0, ret = 0;
   
    //double d1[3] = { 1.1d, 1.2d, 1.3d};
   
    cout<<" program start...\n\nPlease input your file name:\n-> ";
    //writefile(FILENAME, NULL, 0, 0);//构造一个有浮点数据的文本文档
    cin.get(file_in, 512);
    //out.open(FILENAME,ios::in);
    if(strlen(file_in))
    {
        out.open(file_in, ios::in);
        cout<<"\n>>>File \n\t" <<file_in<<"\n   is opened.\n"<<endl;
    }
    else
    {
        out.open(FILENAME, ios::in);
        cout<<"\n>>>You input Nothing! So Open the default file:\n\t" <<FILENAME<<"\n"<<endl;
    }
   
    if(!out)
    {
        cout << "Open file failed!!!" <<endl;
        goto err_out;
    }
   

    while(!out.eof())
    {
       out.getline(buffer,256,'\n');//getline(char *,int,char) 表示该行字符达到256个或遇到换行就结束
       //cout<<buffer<<endl;
       /*
   for(int i=0; i< 5; i++)
       {
            if(i == 0) cout << "\n\t\t" ;
            cout << (unsigned int)buffer[i] << " | " ;
            //if(5 == i) cout <<"\n";
       }
       */
      
       ret = atof_x(buffer, f_buf+n);
       //cout<<"\natof_x return:"<<(ret = atof_x(buffer, f_buf+n)) << " , ";
       //cout <<"f_buf["<<n<<"]: "<< f_buf[n];
       if(ret == -3 )
       {
         cout <<"data end. The data count: " << n << " (最大不能超过 990000 个数据)" << endl;
      break;
       }
      if( (ret == -2)||(ret == -1) )
       {
         cout <<"数据中有数值不是浮点数: " << buffer << " line: "<< n << endl;
      goto err_out;
       }
       ++n;
       /*
       cout <<"\n";
       if(40 == n)
     break;
   */
    }
    /*
    cout <<"\nlast buffer:\n"<< buffer<<endl;
    cout <<"n is : "<< n <<endl;
    cout<<"atof: "<<atof("35.6")<<endl;
   
    cout<< "\n sum is :  " << sum_d(d1, 3)<< endl;
    cout<< "\n aver is :  " << averagex(sum_d(d1, 3), 3)<< endl;
   
    cout << "\n variance is :  "  << variance(d1, averagex(sum_d(d1, 3), 3), 3) <<endl;
    cout << "\n s is :  " << sqrt(variance(d1, averagex(sum_d(d1, 3), 3), 3)) << endl;
    */
    out.close();
   
    cout << "读取了 " << n << " 行数据!" <<endl;
   
    if(n<60)
    {
     cout <<"\n输入数值 不足 60 个,标准差的结果是:" <<
                sqrt(variance(f_buf, averagex(sum_d(f_buf, n), n), n)) << endl;
     goto err_out;
    }
   
    last = n%10;
    count_step = (n - last)/10 -4;
    cout << " Discard Data No: " << last << "; Windows No : " << count_step << endl;
    /*
    for(int x1 =1; x1 <= n/10; ++x1)
    {
     if( (x1*10) > (n-49) )
     {
      count_step = x1 -1;
        break;
     }
    }
    last =( n - (count_step * 10 + 50));
    cout << " last .2 : " << last << "; count_step .2: " << count_step << endl;
    */
    // 计算每个窗口的平均值 和 标准差;   
    for(int x1 = 0; x1 < count_step; ++x1)
    {
     aver_all[x1] = averagex(sum_d((f_buf+10*x1), 50), 50);
     s_all[x1] = sqrt(variance((f_buf+10*x1), aver_all[x1], 50));
    }
    writefile(FILE_AVER, aver_all, count_step, 2);
    writefile(FILE_BZC, s_all, count_step, 2);
    /*
    cout << "\naver_all: " ;
    print_double(aver_all, count_step);
    cout << "s_all: " ;
    print_double(s_all, count_step);
        cout << "\n\nf_buf:\n" ;
    print_double(f_buf, n);
    */
   
    // 计算每个窗口的平均值和标准差后,用每个窗口的数据减掉这个窗口的均值,
    //再除以这个窗口的标准差(标准差是方差的平方根),这列数据就是我要的了
    int x1;
    int x2;
    for(x1 =0; x1 < count_step; ++x1)
    {
      for(x2= (10*x1); x2 < (10*x1+50); ++x2)
      {
              double tmp1 = (f_buf[x2] - aver_all[x1]);
             
              //cout << " "<<x1<<"'"<<x2<<": ";//<< tmp1 <<" ";
              //if((x2-10*x1)%10)
              //  cout << endl;
               //o_buf[x1*50+(x2-10*x1)] =o_buf[x1*40+x2]
              o_buf[x1*50+(x2-10*x1)] =( tmp1/s_all[x1] );
              windatain_buf[x1*50+(x2-10*x1)] = f_buf[x2];
              //if((x1*50+(x2-10*x1))>280)
              //  cout <<"x1*50+(x2-10*x1): "<< (x1*50+(x2-10*x1))<< endl;
         }
//cout << endl;
    }
    //cout <<"x1*50+(x2-10*x1): "<< (x1*50+(x2-10*x1))<< endl;
   
    writefile(FILEOUT, o_buf, count_step*50, 1);
    writefile(FILEOUT2, o_buf, count_step*50, 0);// 输出纯数据的文本文档,便于复制到EXCEL
    //WIN_DATAIN, 步进后的数据源
    writefile(WIN_DATAIN, windatain_buf, count_step*50, 0);
   
    cout << "\n Save the result to File:\n\t"<< FILEOUT << "\n\t"<< FILEOUT2
         << "\n Average saved to File:\n\t"<<FILE_AVER
         << "\n Standard deviation saved to File:\n\t"<<FILE_BZC
         <<"\n\n Please Open it in a txt editor!"<< endl;


err_out:  
    cout << "\n===========>> program end <<<<<< "<< endl;
    cin.get();//cin.get() 是用来读取回车键的,如果没这一行,输出的结果一闪就消失了
    system("pause");
    return 0;
}


double sum_d(double *buf, int len)
{
 double sum = 0.0f;
 for(int i = 0; i < len; ++i)
 {
  sum += buf[i];
 }
 //cout << " <s["<< sum <<"]> ";
 return sum;
}

 


double averagex(double sum, int len)
{
 return sum/len;
}
// 方差
double variance(double* data_in, double aver, int len)
{
 double sum_pf = 0.0f;
 for(int i=0; i<len; ++i)
 {
  sum_pf += ( (data_in[i] - aver)*(data_in[i] - aver) );
 }
 return sum_pf/(len-1);
}

 

 

 


void del_zero(char * buf)
{
    int x1 = strlen(buf) - 1;
    //cout<<"in del_zero: " <<x1<<" -->buf: "<< buf <<" buf[len]: "<< buf[x1]<<endl;
    while((buf[x1]=='0')&&(buf[x1-1]!='.')&&(x1!=0))
    {
        buf[x1]='\0';
        //cout<<"~~~~~~>> " <<buf[x1];
        --x1;
    }
}


int writefile(const char *file, double *datain, int len, int opt)
{
    ofstream out_tofile;
    char strbuf[32];
    double start;
    out_tofile.open(file);
    if(!datain)
    {
        for(int i = 0; i< 100; i++)
        {
            start = 2.0 + ((double)i)/100;
            sprintf(strbuf, "%.12f", start);
            del_zero(strbuf);
            out_tofile<<strbuf<<endl;
        }
    }
    else
    {
        for(int i = 0; i< len; i++)
        {
            if((opt==1)&&(!(i%50)))//如果opt =1 则打印 窗口 序号
                out_tofile << "\n >>>The Window NO: " << (i/50)+1 <<"<<<"<<endl;
            if((opt==2)&&(!(i%20)))//如果opt =2 则打印 窗口范围
                out_tofile << "\n >>>The Window NO: " << (i+1) <<" ~ "<<( ((i+20)>=(len-1))? len :(i+20) )<<" <<<"<<endl;
            sprintf(strbuf, "%.15f", datain[i]);
            //去掉尾部多余的0
            del_zero(strbuf);
            out_tofile<<strbuf<<endl;
        }
    }
    out_tofile<<"end"<<endl;
    out_tofile.close();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值