需求
从文件中读取数据,并判断是否监测到地震.
如果用数字表示震动的幅度,我们不认为诸如1 1 2 3 1 1 1
这样小幅度、正常的波动能代表监测到了地震.
地震监测公式:
短时间窗口取样值/长时间窗口取样值>=1.5
窗口取样值=震动幅度平方和/窗口大小
比如:1 2 1 1 1 5 4 2
这组数据,我们把长时间窗口大小设为5,短时间设为3,那么长时间窗口内的值就是1 1 5 4 2,它的取样值就是(1*1+1*1+5*5+4*4+2*2)/5
,短时间窗口内的值就是5 4 2,取样值为(5*5+4*4+2*2)/3
,两者之比为1.667>1.5,所以认为此时监测到了地震.
我们的需求就是从写好数据的文件中读取数据,并对其进行分析,是否监测到地震.
代码总览:
#include <iostream>
#include <Windows.h>
#include <fstream>
#include <string>
#include <math.h>
#define THRESHOLD 1.5
using namespace std;
double power(double arr[],int length);
int main(void){
string filename;
ifstream file;
int num,ltime,stime;
double *p,*p1,all,scale;
cout<<"请输入分析的文件:";
cin>>filename;
file.open(filename.c_str());
if(file.fail()){//文件打开失败
exit(1);
}
else{
file>>num;
p=new double[num];
for(int i=0;i<num;i++){//原始震动数据导入
file>>p[i];
}
cout<<"请输入监测的短时间窗口大小:";
cin>>stime;
cout<<"请输入监测的长时间窗口大小:";
cin>>ltime;
for(int i=0;i<num-ltime+1;i++){//输出所有的震动比,有num-ltime+1个
p1=new double[ltime];//长震动
for(int j=0;j<ltime;j++){
p1[j]=p[i+j];
}
all=power(p1,ltime);
delete p1;
p1=new double[stime];//短震动
for(int j=0;j<stime;j++){
p1[j]=p[ltime-stime+i+j];
}
scale=power(p1,stime)/all;
cout<<scale;
scale>=THRESHOLD?(cout<<"监测到地震"<<endl):(cout<<endl);
delete p1;
}
delete p;
file.close();
}
system("pause");
return 0;
}
double power(double arr[],int length){
double num=0;
for(int i=0;i<length;i++){
num+=pow(arr[i],2);
}
return num/length;
}
写好的数据放入记事本中,第一行为数据的个数,下面为各数据值.
开始时读取记事本里的内容,这里文件读取的大家都很熟悉了,未成功打开文件则退出:
int main(void){
string filename;
ifstream file;
int num,ltime,stime;
double *p,*p1,all,scale;
cout<<"请输入分析的文件:";
cin>>filename;
file.open(filename.c_str());
if(file.fail()){//文件打开失败
exit(1);
}
else{
......
如果成功打开文件,就将其数据导入到数组中,由于数据的个数是不固定的,所以这里我们使用动态内存分配动态创建数组来存储数据.
else{
file>>num;
p=new double[num];
for(int i=0;i<num;i++){//原始震动数据导入
file>>p[i];
}
cout<<"请输入监测的短时间窗口大小:";
cin>>stime;
cout<<"请输入监测的长时间窗口大小:";
cin>>ltime;
......
输出所有的震动比,11个数据里面有11-(长时间窗口大小)+1个,根据用户的输入为计算长时间窗口取样值和短时间窗口取样值分别动态分配数组,计算完后销毁(一定要记得哦),最后销毁存储原始数据的数组,然后关闭文件.THRESHOLD
在前面有宏定义#define THRESHOLD 1.5
for(int i=0;i<num-ltime+1;i++){//输出所有的震动比,有num-ltime+1个
p1=new double[ltime];//长震动
for(int j=0;j<ltime;j++){
p1[j]=p[i+j];
}
all=power(p1,ltime);
delete p1;
p1=new double[stime];//短震动
for(int j=0;j<stime;j++){
p1[j]=p[ltime-stime+i+j];
}
scale=power(p1,stime)/all;
cout<<scale;
scale>=THRESHOLD?(cout<<"监测到地震"<<endl):(cout<<endl);
delete p1;
}
delete p;
file.close();
......
计算窗口取样值的函数,pow(x,y)返回x的y次方的计算结果,需要包含头文件<math.h>
double power(double arr[],int length){
double num=0;
for(int i=0;i<length;i++){
num+=pow(arr[i],2);
}
return num/length;
}
运行结果:
最后介绍一个函数:内存拷贝函数memcpy()
功能:从源source所指的内存地址的起始位置开始拷贝n个字节到目标destin所指的内存地址的起始位置中
void *memcpy(void *destin, void *source, unsigned n);
destin 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针.
source 指向要复制的数据源,类型强制转换为void* 指针.
n 要被复制的字节数.
在c和c++可用,需要包含头文件.c语言:#include<string.h>
c++:#include<cstring>