ep9_11.cpp
上传用户:wxcui2006
上传日期:2022-07-12
资源大小:1274k
文件大小:6k
- /*9.11 正弦函数在0o~90o的范围中是单调递增的,建立两个文件:一个放sin0o,sin2o,…,sin80o;
- 另一个放sin1o,sin3o,…,sin79o, sin81o,sin82o,…,sin90o,用归并法,把这两个数据文件合并
- 为升序排序的文件,重组为一个完整的sin()函数表文件。*/
- //题解中注释掉的直接读写法与使用成员函数结果完全相同,对于类对象,读和写及占据内存大小均指数据成员, . 仅
- #include<cmath>
- #include<fstream>
- #include<iostream>
- #include<iomanip>
- using namespace std;
- class sinx{
- double Degree;//角度
- double Value;//正弦值
- public:
- sinx(double =0);
- void display();
- void Bdatatofile(fstream &); //流类作为形式参数必须是引用
- void Bdatafromfile(fstream &);
- void datainput(double deg);
- bool operator<=(sinx &);
- bool operator==(sinx &);
- };
- bool sinx::operator<=(sinx & si){
- double k;
- k=Degree-si.Degree;
- if(k<=0) return true;
- else return false;
- }
- bool sinx::operator==(sinx & si){
- double k;
- k=Degree-si.Degree;
- if(k==0) return true;
- else return false;
- }
- sinx::sinx(double deg){
- Degree=deg;
- Value=sin(deg*3.1415926535/180);
- }
- void sinx::display(){
- cout<<setw(10)<<Degree<<setw(10)<<Value<<endl;
- }
- void sinx::datainput(double deg){
- Degree=deg;
- Value=sin(deg*3.1415926535/180);
- }
- void sinx::Bdatatofile(fstream & dest){
- dest.write((char*)&Degree,sizeof(double));
- dest.write((char*)&Value,sizeof(double));
- }
- void sinx::Bdatafromfile(fstream & sour){
- sour.read((char*)&Degree,sizeof(double));
- sour.read((char*)&Value,sizeof(double));
- }//由此可见读和写是完全对称的过程,次序决不能错
- template <typename T>class Array{
- T *elements;
- char name[20];
- int Subscript;//已用最大下标值
- int maxSize;
- fstream datafile;
- public:
- Array(char* ="myfile",int=20);
- ~Array();
- bool IsFull() const{return Subscript==maxSize-1;}
- void renews();//数组扩大一倍
- void ordinsert(T&);//升序输入
- void listshow();//显示数组
- };
- template <typename T> Array<T>::Array(char* filename,int maxs){
- maxSize=maxs;
- Subscript=-1;//私有数据不容许直接赋初值,必须在构造函数中赋初值
- strcpy(name,filename);
- T temp;
- elements=new T[maxSize];
- datafile.open(name,ios::binary|ios::in);
- if(!datafile==0){
- while(!datafile.eof()){
- temp.Bdatafromfile(datafile);
- // datafile.read((char*)&temp,sizeof(T));//直接读写法与使用成员函数结果完全相同
- if(datafile.eof()==0){//读到无数据可读后,即读入不成功,eofbit为1
- ordinsert(temp);
- }
- }
- datafile.close();
- }
- datafile.clear(0);//采用标准库不可少,前面读到过文件结束或打开文件失败,无法恢复
- }
- template <typename T> Array<T>::~Array(){
- int i;
- datafile.open(name,ios::binary|ios::out);
- for(i=0;i<=Subscript;i++)
- elements[i].Bdatatofile(datafile);
- // datafile.write((char*)&elements[i],sizeof(T));//直接读写法与使用成员函数结果完全相同
- datafile.close();
- delete[]elements;
- }
- template <typename T> void Array<T>::renews(){
- int i;
- T *temp=elements;
- maxSize*=2;
- elements=new T[maxSize];
- for(i=0;i<=Subscript;i++) elements[i]=temp[i];
- delete[]temp;
- }
- template <typename T> void Array<T>::ordinsert(T & elem){//以角度为关键字排序
- int i,j;
- if(IsFull()) renews();
- for(i=0;i<=Subscript;i++) if(elem<=elements[i]) break;
- if(!(elem==elements[i])){
- for(j=Subscript;j>=i;j--) elements[j+1]=elements[j];
- Subscript++;
- }
- if(Subscript==-1) Subscript++;//考虑到进入的第一项
- elements[i]=elem;
- }
- template <typename T> void Array<T>::listshow(){
- int i;
- for(i=0;i<=Subscript;i++) elements[i].display();
- }
- //两个文件归并用独立的函数模板
- template <typename T> void Merge(char*filename1,char*filename2,char*filename){
- fstream sdatafile1(filename1,ios::out|ios::in|ios::binary);
- fstream sdatafile2(filename2,ios::out|ios::in|ios::binary);
- fstream ddatafile(filename,ios::out|ios::binary);
- int i=0,j=0,k=0,ns1,ns2;
- T temps1,temps2;
- while(sdatafile1.eof()==0){//侧元素数量,注意会多出一个
- sdatafile1.read((char*)&temps1,sizeof(T));
- i++;
- }
- ns1=i-1;
- cout<<"表1元素数"<<ns1<<endl;
- while(sdatafile2.eof()==0){
- sdatafile2.read((char*)&temps2,sizeof(T));
- j++;
- }
- ns2=j-1;
- cout<<"表2元素数"<<ns2<<endl;
- sdatafile1.clear(0);//用随机方式,一旦用顺序文件方式访问到结束,就必须清状态
- sdatafile2.clear(0);
- i=0;
- j=0;
- sdatafile1.seekg(0,ios::beg);
- sdatafile2.seekg(0,ios::beg);
- // sdatafile1.read((char*)&temps1,sizeof(T));//此方法与用成员函数完全相同
- // sdatafile2.read((char*)&temps2,sizeof(T));//对于类对象,读和写及大小均仅指数据成员
- temps1.Bdatafromfile(sdatafile1);
- temps2.Bdatafromfile(sdatafile2);
- while(i<ns1&&j<ns2){
- if(temps1<=temps2){
- // ddatafile.write((char*)&temps1,sizeof(T));
- // sdatafile1.read((char*)&temps1,sizeof(T));
- temps1.Bdatatofile(ddatafile);
- temps1.Bdatafromfile(sdatafile1);
- i++;
- }
- else{
- // ddatafile.write((char*)&temps2,sizeof(T));//对于类对象,读和写及大小均仅指数据成员
- // sdatafile2.read((char*)&temps2,sizeof(T));//此方法与用成员函数完全相同
- temps2.Bdatatofile(ddatafile);
- temps2.Bdatafromfile(sdatafile2);
- j++;
- }
- }
- while(i<ns1){//复制第一个表的剩余元素
- // ddatafile.write((char*)&temps1,sizeof(T));
- // sdatafile1.read((char*)&temps1,sizeof(T));
- temps1.Bdatatofile(ddatafile);
- temps1.Bdatafromfile(sdatafile1);
- i++;
- }
- while(j<ns2){//复制第二个表的剩余元素
- // ddatafile.write((char*)&temps2,sizeof(T));
- // sdatafile2.read((char*)&temps2,sizeof(T));
- temps2.Bdatatofile(ddatafile);
- temps2.Bdatafromfile(sdatafile2);
- j++;
- }
- sdatafile1.close();
- sdatafile2.close();
- ddatafile.close();
- }
-
- int main(){
- sinx temp;
- int i;
- {//两个正弦表分别在两个块域中定义,域结束时对象存入文件
- Array<sinx> mylist("mydata1");
- cout<<"建立正弦表1(0,2,4,~80度)"<<endl;
- for(i=0;i<=80;i=i+2){
- temp.datainput(i);
- mylist.ordinsert(temp);//除排序外,同时保证二次进入时不会有重复的表项
- }
- mylist.listshow();
- }
- {
- Array<sinx> mylist("mydata2");
- cout<<"建立正弦表2(1,3,5,~81度;82,83,~90)"<<endl;
-
- for(i=82;i<=90;i++){
- temp.datainput(i);
- mylist.ordinsert(temp);
- }
- for(i=1;i<=81;i=i+2){//注意较小的数后入
- temp.datainput(i);
- mylist.ordinsert(temp);
- }
- mylist.listshow();
- }
- Merge<sinx>("mydata1","mydata2","mydata");//按题意要求两个文件归并直接使用文件
- Array<sinx> mylist("mydata");
- cout<<"输出正弦表(0,1,~90度)"<<endl;
- mylist.listshow();
- return 0;
- }
-