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