ep9_11_0.cpp
上传用户:wxcui2006
上传日期:2022-07-12
资源大小:1274k
文件大小:5k
源码类别:

书籍源码

开发平台:

Visual C++

  1. /*9.11 正弦函数在0o~90o的范围中是单调递增的,建立两个文件:一个放sin0o,sin2o,…,sin80o;
  2. 另一个放sin1o,sin3o,…,sin79o, sin81o,sin82o,…,sin90o,用归并法,把这两个数据文件合并
  3. 为升序排序的文件,重组为一个完整的sin()函数表文件。*/
  4. //题解中使用的直接读写法与成员函数结果完全相同,对于类对象,读和写及占据内存大小均指数据成员。
  5. //本例未用链表类,但用函数模板
  6. #include<cmath>
  7. #include<fstream>
  8. #include<iostream>
  9. #include<iomanip>
  10. using namespace std;
  11. class sinx{
  12. double Degree;//角度
  13. double Value;//正弦值
  14. public:
  15. sinx(double =0);
  16. void display();
  17. void datainput(double deg);
  18. bool operator<=(sinx &);
  19. bool operator==(sinx &);
  20. };
  21. bool sinx::operator<=(sinx & si){
  22. double k;
  23. k=Degree-si.Degree;
  24. if(k<=0) return true;
  25. else return false;
  26. }
  27. bool sinx::operator==(sinx & si){
  28. double k;
  29. k=Degree-si.Degree;
  30. if(k==0) return true;
  31. else return false;
  32. }
  33. sinx::sinx(double deg){
  34. Degree=deg;
  35. Value=sin(deg*3.1415926535/180);
  36. }
  37. void sinx::display(){
  38. cout<<setw(10)<<Degree<<setw(10)<<Value<<endl;
  39. }
  40. void sinx::datainput(double deg){
  41. Degree=deg;
  42. Value=sin(deg*3.1415926535/180);
  43. }
  44. template <typename T> void listshow(T*elements,int subsc){
  45. int i;
  46. for(i=0;i<=subsc;i++) elements[i].display();
  47. }
  48. template <typename T> void ordinsert(T & elem,T*elements,int subsc){//以角度为关键字排序
  49. int i,j;
  50. for(i=0;i<=subsc-1;i++) if(elem<=elements[i]) break;
  51. if(!(elem==elements[i])){
  52. for(j=subsc-1;j>=i;j--) elements[j+1]=elements[j];
  53. }
  54. elements[i]=elem;
  55. }
  56. template <typename T> int readfile(char* filename,T*elements){//由文件写入链表,返回最大下标
  57. int k=-1;
  58. T temp;
  59. ifstream datafile;
  60. datafile.open(filename,ios::binary|ios::in);
  61. while(!datafile.eof()){
  62. datafile.read((char*)&temp,sizeof(T));
  63.         if(datafile.eof()==0){//读到无数据可读后,即读入不成功,eofbit为1
  64. k++;
  65. ordinsert(temp,elements,k);
  66. }
  67. }
  68. datafile.close();
  69. return k;
  70. }
  71. template <typename T> void writefile(char* filename,T*elements,int subsc){
  72. int i;
  73. ofstream datafile;
  74. datafile.open(filename,ios::binary|ios::out);
  75. for(i=0;i<=subsc;i++)
  76. datafile.write((char*)&elements[i],sizeof(T));
  77. datafile.close();
  78. }
  79. //两个文件归并用独立的函数模板
  80. template <typename T> void Merge(char*filename1,char*filename2,char*filename){
  81. fstream sdatafile1(filename1,ios::out|ios::in|ios::binary);
  82. fstream sdatafile2(filename2,ios::out|ios::in|ios::binary);
  83. fstream ddatafile(filename,ios::out|ios::binary);
  84. int i=0,j=0,k=0,ns1,ns2;
  85. T temps1,temps2;
  86. while(sdatafile1.eof()==0){//求文件所含数据数量
  87. sdatafile1.read((char*)&temps1,sizeof(T));
  88. i++;
  89. }
  90. ns1=i-1;
  91. while(sdatafile2.eof()==0){
  92. sdatafile2.read((char*)&temps2,sizeof(T));
  93. j++;
  94. }
  95. ns2=j-1;
  96. sdatafile1.clear(0);
  97. sdatafile2.clear(0);
  98.     i=0;
  99. j=0;
  100. sdatafile1.seekg(0,ios::beg);
  101. sdatafile2.seekg(0,ios::beg);
  102. sdatafile1.read((char*)&temps1,sizeof(T));//此方法与用成员函数完全相同
  103. sdatafile2.read((char*)&temps2,sizeof(T));//对于类对象,读和写及大小均仅指数据成员
  104. while(i<ns1&&j<ns2){
  105. if(temps1<=temps2){
  106. ddatafile.write((char*)&temps1,sizeof(T));
  107. sdatafile1.read((char*)&temps1,sizeof(T));
  108. i++;
  109. }
  110. else{
  111. ddatafile.write((char*)&temps2,sizeof(T));//对于类对象,读和写及大小均仅指数据成员
  112. sdatafile2.read((char*)&temps2,sizeof(T));//此方法与用成员函数完全相同
  113. j++;
  114. }
  115. }
  116. while(i<ns1){//复制第一个表的剩余元素
  117. ddatafile.write((char*)&temps1,sizeof(T));
  118. sdatafile1.read((char*)&temps1,sizeof(T));
  119. i++;
  120. }
  121. while(j<ns2){//复制第二个表的剩余元素
  122. ddatafile.write((char*)&temps2,sizeof(T));
  123. sdatafile2.read((char*)&temps2,sizeof(T));
  124. j++;
  125. }
  126. sdatafile1.close();
  127. sdatafile2.close();
  128. ddatafile.close();
  129. }
  130. int main(){
  131. sinx temp,list1[100],list2[100],list[100];
  132. int i,k1,k2,k3;
  133. cout<<"建立正弦表1(0,2,4,~80度)"<<endl;
  134. k1=-1;
  135. for(i=0;i<=80;i=i+2){
  136. temp.datainput(i);
  137. k1++;
  138. ordinsert(temp,list1,k1);//除排序外,同时保证二次进入时不会有重复的表项
  139. }
  140. writefile("mydata1",list1,k1);
  141. temp.datainput(0);
  142. for(i=0;i<=k1;i++) list1[i]=temp;//数组清空,以便检验文件
  143. k1=readfile("mydata1",list1);//由文件重新写入数组
  144. listshow(list1,k1);
  145. cout<<"建立正弦表2(1,3,5,~81度;82,83,~90度)"<<endl;
  146. k2=-1;
  147. for(i=82;i<=90;i++){
  148. temp.datainput(i);
  149. k2++;
  150. ordinsert(temp,list2,k2);
  151. }
  152. for(i=1;i<=81;i=i+2){
  153. temp.datainput(i);
  154. k2++;
  155. ordinsert(temp,list2,k2);//除排序外,同时保证二次进入时不会有重复的表项
  156. }
  157. writefile("mydata2",list2,k2);
  158. temp.datainput(0);
  159. for(i=0;i<=k2;i++) list2[i]=temp;//数组清空,以便检验文件
  160. k2=readfile("mydata2",list2);//由文件重新写入数组
  161. listshow(list2,k2);
  162. //按题意要求两个文件归并直接使用文件
  163.     Merge<sinx>("mydata1","mydata2","mydata");
  164. cout<<"输出正弦表(0,1,~90度)"<<endl;
  165. k3=readfile("mydata",list);//由文件重新写入数组
  166. listshow(list,k3);
  167. return 0;
  168. }