c++第六次作业——算法终极优化
part 2:
1 // 合并两个文件内容到一个新文件中。 2 // 文件名均从键盘输入 3 4 #include <iostream> 5 #include <fstream> 6 #include <string> 7 #include <cstdlib> 8 using namespace std; 9 10 int main() { 11 char filename1[10], filename2[10], newfilename[10]; 12 13 cout << "输 入要合并的两个文件名: " ; 14 gets(filename1); gets(filename2); 15 cout << "输 入合并后新文件名: " ; 16 cin >> newfilename; 17 18 ofstream fout; // 输出文件流对象 19 ifstream fin; // 输入文件流对象 20 21 22 fin.open(filename1); // 将输入文件流对象fin与文件filename1建立关联 23 if(!fin.is_open()) { // 如果打开文件失败,则输出错误提示信息并退出 24 cerr << "fail to open file " << filename1 << endl; 25 system("pause"); 26 exit(0); 27 } 28 29 fout.open(newfilename); // 将输出文件流对象fout与文件newfilename建立关联 30 if(!fin.is_open()) { // 如果创建/打开文件失败,输出错误提示信息并退出 31 cerr << "fail to open file " << newfilename << endl; 32 system("pause"); 33 exit(0); 34 } 35 36 char ch; 37 38 // 从文件输入流对象fin中获取字符,并将其插入到文件输出流对象fout中 39 while(fin.get(ch)) 40 fout << ch; 41 42 fin.close(); // 关闭文件输入流对象fin与文件filename1的关联 43 44 fout << endl; // 向文件输出流对象fout中插入换行 45 46 47 fin.open(filename2); // 将输入文件流对象fin与文件filename2建立关联 48 if(!fin.is_open()) { // 如果打开文件失败,则输出错误提示信息并退出 49 cerr << "fail to open file " << filename2 << endl; 50 system("pause"); 51 exit(0); 52 } 53 54 // 从文件输入流对象fin中获取字符,并将其插入到文件输出流对象fout中 55 while(fin.get(ch)) 56 fout << ch; 57 58 fin.close(); // 关闭文件输入流对象fin与文件filename2的关联 59 60 fout<<"\nmerge successfully."<<endl; 61 fout.close(); // 关闭文件输出流对象fout与文件newfilename的关联 62 63 system("pause"); 64 65 return 0; 66 } 67 68 // 说明: 69 // 这个简单示例中,合并两个文件的具体方法,是逐个读取文件中的字符直到文件末尾,并写入到新文件中 70 // 还可以一次读取一行 71 // 或者,直接利用标准模板库的成员函数,一次性将整个文件内容读取至缓冲区 72 // 等过了期末考,时间宽松一些的时候可以学习体验更多标准模板库的内容,对后续专业课的学习(如数据结构、算法、操作系统等)也会有帮助

part 3:
第一题、
这题需要生成项目,这里只有关键代码。
阶段一:初实验:
1 #include <iostream> 2 #include <string> 3 #include "utils.h" 4 #include <cstring> 5 #include <cstdlib> 6 #include <fstream> 7 #include <ctime> 8 using namespace std; 9 10 int main() { 11 12 string filename; 13 14 filename = getCurrentDate(); 15 16 cout << "日 期:" << filename << endl; 17 18 19 char file1[100]; 20 cout<<"请 输入文件:"; 21 gets(file1); 22 int n; 23 cout<<"请 输入抽取人数:"; 24 cin>>n; 25 26 ofstream fout; 27 ifstream fin; 28 fin.open(file1); 29 if(!fin.is_open()){ 30 cerr << "fail to open file " << file1 << endl; 31 system("pause"); 32 exit(0); 33 } 34 char date[100]; 35 strcpy(date,filename.c_str()); 36 char *txt=".txt"; 37 strcat(date,txt); 38 cout<<"输 出文件名:"<<date<<endl; 39 fout.open(date); 40 if(!fin.is_open()){ 41 cerr << "fail to open file " << date << endl; 42 system("pause"); 43 exit(0); 44 } 45 46 int num=0; 47 string a[100]; 48 ifstream infile(file1); 49 while(!infile.eof()){ 50 getline(infile,a[num],'\n'); 51 num++; 52 } 53 int luck[100]; 54 int k=0; 55 do{ 56 srand((int)time(0)); 57 for(int i=0;i<n;i++) 58 luck[i]=rand()%num; 59 for(int i=0;i<n;i++) 60 for(int j=i+1;j<n;j++) 61 if(luck[i]==luck[j]){ 62 k=1;break; 63 } 64 }while(k); 65 66 for(int i=0;i<n;i++){ 67 fout<<a[luck[i]]<<endl; 68 cout<<a[luck[i]]<<endl; 69 } 70 71 fin.close(); 72 fout.close(); 73 return 0; 74 }


阶段二:
2019/6/9
更新部分程序段:
1、调整逻辑;
2、支持读取失败后重新输入;
3、名单升序排列。
1 #include <iostream> 2 #include <string> 3 #include "utils.h" 4 #include <cstring> 5 #include <cstdlib> 6 #include <fstream> 7 #include <ctime> 8 using namespace std; 9 10 int main() { 11 12 string filename; 13 14 filename = getCurrentDate(); 15 16 cout << "日 期:" << filename << endl; 17 18 19 char file1[100]; 20 cout<<"请 输入文件:"; 21 gets(file1); 22 23 ofstream fout; 24 ifstream fin; 25 fin.open(file1); 26 while(!fin.is_open()){ 27 cerr << "打 开文件 " << file1 <<" 失败!"<< endl; 28 system("pause"); 29 cout<<"请 重新输入文件: "; 30 gets(file1); 31 fin.open(file1); 32 } 33 34 int num=0; 35 string a[1000]; 36 ifstream infile(file1); 37 while(!infile.eof()){ 38 getline(infile,a[num],'\n'); 39 num++; 40 } 41 42 int n; 43 cout<<"请 输入抽取人数:"; 44 cin>>n; 45 while(n>num){ 46 cout<<"抽 取人数超过名单人数!\n" 47 <<"请 重新输入抽取人数:"; 48 cin>>n; 49 } 50 51 char date[100]; 52 strcpy(date,filename.c_str()); 53 char *txt=".txt"; 54 strcat(date,txt); 55 cout<<"输 出文件名:"<<date<<endl; 56 fout.open(date); 57 if(!fin.is_open()){ 58 cerr << "fail to open file " << date << endl; 59 system("pause"); 60 exit(0); 61 } 62 63 int luck[1000]; 64 int k=0; 65 do{ 66 srand((int)time(0)); 67 for(int i=0;i<n;i++) 68 luck[i]=rand()%num; 69 for(int i=0;i<n;i++) 70 for(int j=i+1;j<n;j++) 71 if(luck[i]==luck[j]){ 72 k=1;break; 73 } 74 }while(k); 75 76 for(int i=0;i<n;i++){ 77 int min=i; 78 for(int j=i+1;j<n;j++) 79 if(luck[min]>luck[j]) min=j; 80 if(min!=i){ 81 int t=luck[min]; 82 luck[min]=luck[i]; 83 luck[i]=t; 84 } 85 } 86 for(int i=0;i<n;i++){ 87 fout<<a[luck[i]]<<endl; 88 cout<<a[luck[i]]<<endl; 89 } 90 91 fin.close(); 92 fout.close(); 93 return 0; 94 }


阶段三:
2019/6/11
1、优化算法;
2、增加过渡环节(避免误以为卡死)。
1 #include <iostream> 2 #include <string> 3 #include "utils.h" 4 #include <cstring> 5 #include <cstdlib> 6 #include <fstream> 7 #include <ctime> 8 using namespace std; 9 10 void fun1(int luck[],int n,char date[],int num);//生成随机数 11 void fun2(int luck[],int n);//升序排序 12 13 void fun1(int luck[],int n,char date[],int num){ 14 for(int i=0;i<n;i++){ 15 cout<<"输 出文件名:"<<date<<endl; 16 cout<<"列 表生成中,已完成"<<(int)((double)i/(double)n*100.0)<<"%\n"; 17 luck[i]=rand()%num; 18 int j=0,k=0; 19 for(;j<i;j++) 20 if(luck[i]==luck[j]){ 21 k=1; 22 while(k){ 23 srand((double)time(0)); 24 luck[i]=rand()%num; 25 if(luck[i]!=luck[j]) { 26 int t=0; 27 for(;t<i;t++) 28 if(luck[t]==luck[i]) break; 29 if(t==i) k=0; 30 } 31 } 32 } 33 system("cls"); 34 } 35 } 36 37 void fun2(int luck[],int n){ 38 for(int i=0;i<n;i++){ 39 int min=i; 40 for(int j=i+1;j<n;j++) 41 if(luck[min]>luck[j]) min=j; 42 if(min!=i){ 43 int t=luck[min]; 44 luck[min]=luck[i]; 45 luck[i]=t; 46 } 47 } 48 } 49 50 int main() { 51 52 string filename; 53 54 filename = getCurrentDate(); 55 56 cout << "日 期:" << filename << endl; 57 58 char file1[100]; 59 cout<<"请 输入文件:"; 60 gets(file1); 61 62 ofstream fout; 63 ifstream fin; 64 fin.open(file1); 65 while(!fin.is_open()){ 66 cerr << "打 开文件 " << file1 <<" 失败!"<< endl; 67 system("pause"); 68 cout<<"请 重新输入文件: "; 69 gets(file1); 70 fin.open(file1); 71 } 72 73 int num=0; 74 string a[1000]; 75 ifstream infile(file1); 76 while(!infile.eof()){ 77 getline(infile,a[num],'\n'); 78 num++; 79 } 80 81 int n; 82 cout<<"请 输入抽取人数:"; 83 cin>>n; 84 while(n>num){ 85 cout<<"抽 取人数超过名单人数!"<<endl; 86 cout<<"请 重新输入抽取人数:"; 87 cin>>n; 88 } 89 90 char date[100]; 91 strcpy(date,filename.c_str()); 92 char *txt=".txt"; 93 strcat(date,txt); 94 fout.open(date); 95 if(!fin.is_open()){ 96 cerr << "生 成失败! " << date << endl; 97 system("pause"); 98 exit(0); 99 } 100 101 system("cls"); 102 int luck[n]; 103 srand((double)time(0)); 104 if(n<=num/2||n<=num/2+1){ 105 fun1(luck,n,date,num); 106 fun2(luck,n); 107 } 108 else{ 109 int tluck[num-n]; 110 fun1(tluck,num-n,date,num); 111 fun2(tluck,num-n); 112 int tluckn=0,luckn=0; 113 for(int i=0;i<n;i++){ 114 while(luckn==tluck[tluckn]) 115 luckn++; 116 luck[i]=luckn; 117 luckn++; 118 } 119 } 120 121 cout<<"输 出文件名:"<<date<<endl; 122 for(int i=0;i<n;i++){ 123 fout<<a[luck[i]]<<endl; 124 cout<<a[luck[i]]<<endl; 125 } 126 127 fin.close(); 128 fout.close(); 129 return 0; 130 }




阶段四:
阶段三要40+s 才能完成目标,太慢了。
我还能更快。
2019/6/11晚,受文艺复兴启发,
算法终极优化,彻底避免重复和卡机。
1 #include <iostream> 2 #include <string> 3 #include "utils.h" 4 #include <cstring> 5 #include <cstdlib> 6 #include <fstream> 7 #include <ctime> 8 using namespace std; 9 10 void fun1(int luck[],int n,int num,int i,int all[]);//生成随机数 11 void fun2(int luck[],int n);//升序排序 12 13 void fun1(int luck[],int n,int num,int i,int all[]){ 14 if(i<n){ 15 srand((double)time(0)); 16 int t=rand()%num; 17 luck[i]=all[t]; 18 for(int j=t;j<num-1;j++) 19 all[j]=all[j+1]; 20 fun1(luck,n,num-1,i+1,all); 21 } 22 } 23 24 void fun2(int luck[],int n){ 25 for(int i=0;i<n;i++){ 26 int min=i; 27 for(int j=i+1;j<n;j++) 28 if(luck[min]>luck[j]) min=j; 29 if(min!=i){ 30 int t=luck[min]; 31 luck[min]=luck[i]; 32 luck[i]=t; 33 } 34 } 35 } 36 37 int main() { 38 39 string filename; 40 41 filename = getCurrentDate(); 42 43 cout << "日 期:" << filename << endl; 44 45 char file1[100]; 46 cout<<"请 输入文件:"; 47 gets(file1); 48 49 ofstream fout; 50 ifstream fin; 51 fin.open(file1); 52 while(!fin.is_open()){ 53 cerr << "打 开文件 " << file1 <<" 失败!"<< endl; 54 system("pause"); 55 cout<<"请 重新输入文件: "; 56 gets(file1); 57 fin.open(file1); 58 } 59 60 int num=0; 61 string a[1000]; 62 ifstream infile(file1); 63 while(!infile.eof()){ 64 getline(infile,a[num],'\n'); 65 num++; 66 } 67 68 int n; 69 cout<<"请 输入抽取人数:"; 70 cin>>n; 71 while(n>num){ 72 cout<<"抽 取人数超过名单人数!"<<endl; 73 cout<<"请 重新输入抽取人数:"; 74 cin>>n; 75 } 76 77 char date[100]; 78 strcpy(date,filename.c_str()); 79 char *txt=".txt"; 80 strcat(date,txt); 81 fout.open(date); 82 if(!fin.is_open()){ 83 cerr << "生 成失败! " << date << endl; 84 system("pause"); 85 exit(0); 86 } 87 88 int all[num]; 89 for(int i=0;i<num;i++) 90 all[i]=i; 91 int luck[n]; 92 if(n<=num/2||n<=num/2+1){ 93 fun1(luck,n,num,0,all); 94 fun2(luck,n); 95 } 96 else{ 97 int tluck[num-n]; 98 fun1(tluck,num-n,num,0,all); 99 fun2(tluck,num-n); 100 int tluckn=0,luckn=0; 101 for(int i=0;i<n;i++){ 102 while(luckn==tluck[tluckn]) 103 luckn++; 104 luck[i]=luckn; 105 luckn++; 106 } 107 } 108 109 cout<<"输 出文件名:"<<date<<endl; 110 for(int i=0;i<n;i++){ 111 fout<<a[luck[i]]<<endl; 112 cout<<a[luck[i]]<<endl; 113 } 114 115 fin.close(); 116 fout.close(); 117 return 0; 118 }


第二题、
1 #include <iostream> 2 #include <fstream> 3 #include <string> 4 using namespace std; 5 6 int main() { 7 char filename1[10], filename2[10], newfilename[10]; 8 9 cout << "输 入文件名:" ; 10 gets(filename1); 11 12 ifstream fin; 13 14 fin.open(filename1); 15 if(!fin.is_open()) { 16 cerr << "fail to open file " << filename1 << endl; 17 system("pause"); 18 exit(0); 19 } 20 21 char ch; 22 int numstr=0,numword=0,numline=0; 23 int k=1; 24 while(fin.get(ch)){ 25 if(ch==' '){ 26 numstr++; 27 if(k==0) k=1; 28 } 29 else if(ch=='\n'){ 30 numline++; 31 if(k==0) k=1; 32 } 33 else if(k&&((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))){ 34 numword++;numstr++;k=0; 35 } 36 else numstr++; 37 } 38 if(ch=='\n') numline--; 39 else numline++; 40 cout<<"字 符数:"<<numstr<<"\n" 41 <<"单 词数:"<<numword<<"\n" 42 <<"行 数:"<<numline<<endl; 43 fin.close(); 44 45 return 0; 46 }

问题:
1、error: no matching function for call to 'std::basic_ifstream<char>::open(std::string&)
没有c++11的解决方案:
例如代码:
1 string filename = "1.txt"; 2 ifstream fin; 3 fin.open(filename);
error: no matching function for call to 'std::basic_ifstream<char>::open(std::string&)
原因是C++的string类无法作为open的参数。
解决方案:使用C的字符串。
char filename[10]; strcpy(filename, "1.txt"); ifstream fin; fin.open(filename);
注:转载自:https://www.cnblogs.com/cszlg/archive/2012/12/15/2910424.html
2、string类转为char类:
1 #include<cstring> 2 …… 3 …… 4 …… 5 string filename; 6 filename=getCurrentDate(); 7 cahr filename_in_char[100]; 8 strcpy(filename_in_char,filename.c_str()); 9 …… 10 …… 11 ……
这只是个模板,根据自己需求改。
3、按时间生成随机数:
头文件:
个人感觉:
1、高重复率:
srand((int)time(0));
2、低重复率:
srand((double)time(0));

浙公网安备 33010602011771号