📄 ep9_11_0.cpp
字号:
/*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 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);
}
template <typename T> void listshow(T*elements,int subsc){
int i;
for(i=0;i<=subsc;i++) elements[i].display();
}
template <typename T> void ordinsert(T & elem,T*elements,int subsc){//以角度为关键字排序
int i,j;
for(i=0;i<=subsc-1;i++) if(elem<=elements[i]) break;
if(!(elem==elements[i])){
for(j=subsc-1;j>=i;j--) elements[j+1]=elements[j];
}
elements[i]=elem;
}
template <typename T> int readfile(char* filename,T*elements){//由文件写入链表,返回最大下标
int k=-1;
T temp;
ifstream datafile;
datafile.open(filename,ios::binary|ios::in);
while(!datafile.eof()){
datafile.read((char*)&temp,sizeof(T));
if(datafile.eof()==0){//读到无数据可读后,即读入不成功,eofbit为1
k++;
ordinsert(temp,elements,k);
}
}
datafile.close();
return k;
}
template <typename T> void writefile(char* filename,T*elements,int subsc){
int i;
ofstream datafile;
datafile.open(filename,ios::binary|ios::out);
for(i=0;i<=subsc;i++)
datafile.write((char*)&elements[i],sizeof(T));
datafile.close();
}
//两个文件归并用独立的函数模板
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;
while(sdatafile2.eof()==0){
sdatafile2.read((char*)&temps2,sizeof(T));
j++;
}
ns2=j-1;
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));//对于类对象,读和写及大小均仅指数据成员
while(i<ns1&&j<ns2){
if(temps1<=temps2){
ddatafile.write((char*)&temps1,sizeof(T));
sdatafile1.read((char*)&temps1,sizeof(T));
i++;
}
else{
ddatafile.write((char*)&temps2,sizeof(T));//对于类对象,读和写及大小均仅指数据成员
sdatafile2.read((char*)&temps2,sizeof(T));//此方法与用成员函数完全相同
j++;
}
}
while(i<ns1){//复制第一个表的剩余元素
ddatafile.write((char*)&temps1,sizeof(T));
sdatafile1.read((char*)&temps1,sizeof(T));
i++;
}
while(j<ns2){//复制第二个表的剩余元素
ddatafile.write((char*)&temps2,sizeof(T));
sdatafile2.read((char*)&temps2,sizeof(T));
j++;
}
sdatafile1.close();
sdatafile2.close();
ddatafile.close();
}
int main(){
sinx temp,list1[100],list2[100],list[100];
int i,k1,k2,k3;
cout<<"建立正弦表1(0,2,4,~80度)"<<endl;
k1=-1;
for(i=0;i<=80;i=i+2){
temp.datainput(i);
k1++;
ordinsert(temp,list1,k1);//除排序外,同时保证二次进入时不会有重复的表项
}
writefile("mydata1",list1,k1);
temp.datainput(0);
for(i=0;i<=k1;i++) list1[i]=temp;//数组清空,以便检验文件
k1=readfile("mydata1",list1);//由文件重新写入数组
listshow(list1,k1);
cout<<"建立正弦表2(1,3,5,~81度;82,83,~90度)"<<endl;
k2=-1;
for(i=82;i<=90;i++){
temp.datainput(i);
k2++;
ordinsert(temp,list2,k2);
}
for(i=1;i<=81;i=i+2){
temp.datainput(i);
k2++;
ordinsert(temp,list2,k2);//除排序外,同时保证二次进入时不会有重复的表项
}
writefile("mydata2",list2,k2);
temp.datainput(0);
for(i=0;i<=k2;i++) list2[i]=temp;//数组清空,以便检验文件
k2=readfile("mydata2",list2);//由文件重新写入数组
listshow(list2,k2);
//按题意要求两个文件归并直接使用文件
Merge<sinx>("mydata1","mydata2","mydata");
cout<<"输出正弦表(0,1,~90度)"<<endl;
k3=readfile("mydata",list);//由文件重新写入数组
listshow(list,k3);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -