⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ep9_11.cpp

📁 这里有大量的c语言习题呢!真的是题海哦
💻 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 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;
}
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -