病毒感染之文件读入输出
检测n个人的DNA与一串病毒串是否有匹配的部分,其中病毒为环状即不只是简单的一个规定长度的串了
下面讲讲解题的思路吧
首先不管三七二十一先写个大框架即主函数
方法:定义两个串,用freopen(输入文件名,“r读入”,stdin) freopen(输出文件,“w写入”,stdout),读入检测人员数,用一个循环从1开始进行读入母串与模式串,比较返回结果,根据结果输出
int main() { string s,t; int n; freopen("输入数据.txt","r",stdin); freopen("输出结果.txt","w",stdout); cin>>n; //用文件的数字作为个数N for(int i=1;i<=n;++i) { cin>>t>>s; //cout<<s<<t cout<<t<<" "<<s<<" "; if(virus_detection(s,t)==1) //返回结果感染为1,未感染为0 cout<<"yes"<<endl; else cout<<"no"; } return 0; //遇到了只输出一句的情况原来是因为把return 0放在了循环内导致第一次循环结束就是整个循环结束了 }
继续细化接口函数virus-detection
方法:用t+=t来把原模式串加长为两倍然后每次截取原模式串长度的串作为新的模式串来与母串比较,用标志获取结果(是否有匹配的部分),根据结果返回是否感染
int virus_detection(string s,string t) { //检测是否感染 int num=t.length(); int flag; //定义一个标志来记录模式与母串的匹配结果 string temp; //新的串做为每次比较的模式串 t+=t; //病毒串加倍 for(int i=0;i<num;i++) { temp.assign(t,i,num); // 将t的内容从位置i起的num个字符作为原字串的新内容赋给原字串 flag=index_bf(s,temp,1); //返回比较结果,匹配为位置,不匹配为-1 if(flag!=-1) //!(不匹配即未感染返回结果-1)即感染 return 1; } return 0; //未感染返回0 }
关于string类的assign函数用法:
a. string& assign ( const string& str );
将str替换原字串的内容
b. string& assign ( const string& str, size_t pos, size_t n );
将str的内容从位置pos起的n个字符作为原字串的新内容赋给原字串
d. string& assign ( const char* s );
将字符串或者字符数组作为新内容替换原字串
e. string& assign ( size_t n, char c );
将原字串替换为n个字符
最后一步细化index-bf函数
方法:这个就是书本上的简单的bf算法,两个串均未到末尾就逐一比较每个字符,如果相等就两个串都往后移一个位置,否则i回到i-j+1(其实就是原来初始i的下一个),j回到0号下标位置,这里要注意这道题不是从1开始而是从坐标0开始
int index_bf(string s,string t,int pos) { int i=pos-1; int j=0; while(i<s.length()&&j<t.length()) { if(s[i]==t[j]) { ++i; ++j; } else { i=i-j+1; //i=i-j-1 j=0; } } if(j==t.length()) return i-t.length(); //匹配返回位置 else return -1; //不匹配返回-1 }
freopen函数
重定向输出,就是可以把原本只是输出在控制台的字符,输出到你指定的路径文件中。(输入类似,就是从指定的文件中读取,而不是读取在控制台中的输入。)重定向函数可以在任何时候开启、关闭。
函数名:freopen
标准声明:FILE *freopen( const char *path, const char *mode, FILE *stream );
所在文件: <stdio.h>
path: 文件名,用于存储输入输出的自定义文件名。
mode: 文件打开的模式。和fopen中的模式(如r-只读, w-写)相同。
stream: 一个文件,通常使用标准流文件。
返回值:成功,则返回一个path所指定文件的指针;失败,返回NULL。
功能:实现重定向,把预定义的标准流文件定向到由path指定的文件中。标准流文件具体是指stdin、stdout和stderr。其中stdin是标准输入流,默认为键盘;stdout是标准输出流,默认为屏幕;stderr是标准错误流,一般把屏幕设为默认。
例如:
#include <stdio.h> #include <iostream> int main() { int a,b; freopen("D:\\in.txt","r",stdin); //输入重定向,输入数据将从D盘根目录下的in.txt文件中读取 freopen("D:\\out.txt","w",stdout); //输出重定向,输出数据将保存在D盘根目录下的out.txt文件中 while(cin>>a>>b) cout<<a+b<<endl; // 注意使用endl fclose(stdin);//关闭重定向输入 fclose(stdout);//关闭重定向输出 return 0; }