前言 我的书是严那版的 涉及了一点点文件操作 我先写一点点
只想问字符串 到底还有多少惊喜是朕不知道的
字符串中size()、length()与sizeof()用法及区别
length是因为C语言的习惯而保留下来的,string类最初只有length,引进STL后 为了兼容 又添加了size。也就是两者没有任何区别 今天偶尔看到 提一嘴
字符串的size()函数返回字符串的长度,不包括结束符’\0’。
操作符(操作符 不是函数)sizeof(类型名 或 表达式)返回一个对象或者类型所占的内存字节数
在C++中 关于stream类 所有的I/O都以这个“流”类为基础的,包括文件I/O,stream这个类有两个重要的运算符:
1、插入器(<<)
向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下指的显示器,所以,cout<<“妮妮是最棒哒”<<’\n’;就表示把字符串"妮妮是最棒哒"和换行字符(’\n’)输出到标准输出流。
2、析取器(>>)
从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下指的键盘,所以,cin>>x就表示从标准输入流中读取一个变量x的类型的数据。
在C++中,对文件的操作是通过fstream来实现的,所以,用这种方式操作文件,就必须加入头文件fstream。
在实际应用中,根据需要的不同,选择不同的类来定义:
如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
一、打开文件
在fstream类中成员函数open(),就是用来打开文件的,其原型是:
void open(const char* filename,int mode,int access);
类 默认方式
ofstream ios::out | ios::trunc
ifstream ios::in
fstream ios::in | ios::out
参数:
filename: 要打开的文件名
mode: 要打开文件的方式
access: 打开文件的属性
打开文件的属性取值是:
0:普通文件,打开访问
1:只读文件
2:隐含文件
4:系统文件
可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件
ios::app: 以追加的方式打开文件
ios::ate: 文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
ios::in: 文件以输入方式打开(文件数据输入到内存)
ios::out: 文件以输出方式打开(内存数据输出到文件)
ios::nocreate: 不建立文件,所以文件不存在时打开失败
ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败
ios::trunc: 如果文件存在,把文件长度设为0
算了吧我不记下次就是说用到的时候再看看
如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:
file1.open(“c:\config.sys”); <=> file1.open(“c:\config.sys”,ios::in|ios::out,0);
(切记文件名要打双引号)
ifstream file2(“c:\pdos.def”);//以输入方式打开文件
ofstream file3(“c:\x.123”);//以输出方式打开文件
fout对象的作用可以理解成:向文件中进行写操作 【从缓冲区–>硬盘】
fin对象的作用可以理解成:对文件中的内容进行读操作 【从硬盘–>缓冲区】
二、关闭文件
打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。
进入病毒检测的正文啦
首先要确保自己对kmp和bf算法了解(bf要自己会实现 kmp要掌握next数组和nextval数组的求法)老师说kmp就算没有完全了解其原理也没有关系
如果还有朋友对教材上的讲解不了解的话 可以看一下《大话数据结构》这本书 讲的深入浅出 非常有逻辑
一、实验题目
医学研究者最近发现了某些新病毒,通过对这些病毒的分析,得知它们的 DNA 序列都是环状的。现在研究者巳收集了大量的病毒 DNA 和人的 DNA 数据,想快速检测出这些人是否感染了相应的病毒。为了方便研究,研究者将人的 DNA 和病毒 DNA 均表示成由一些字母组成的字符串序列,然后检测某种病毒 DNA 序列是否在患者的 DNA 序列中出现过,如果出现过,则此人感染了该病毒,否则没有感染。 例如, 假设病毒的 DNA 序列为 baa, 患者 1 的 DNA 序列为 aaabbba,则感染, 患者 2 的 DNA 序列为 babbba, 则未感染。(注意,人的 DNA 序列是线性的, 而病毒的DNA 序列是环状的)
此题特殊就特殊在 环状
假设病毒 DNA 序列的长度是 m, 因为病毒 DNA 序列是环状的 ,为了线性取到每个可行的长度为 m 的模式串,可将存储病毒DNA序列的字符串长度扩大为 2m,将病毒DNA序列连续存储两次。然后循环m次,依次取得每个长度为m的环状字符串,将此字符串作为模式串,将人的DNA序列作为主串,调用BF算法进行模式匹配。 只要匹配成功,即可中止循环,表明该人感染了对应的病毒。
(先写这一部分的代码)
m=Virus.length; //病毒 DNA 序列的长度是 mfor(int i=m+1, j=l; j<=m; j++) //将病毒字符串的长度扩大2倍Virus.ch[i++]=Virus.ch[j]; //根据优先级相当于{Virus.ch[i]=Virus.ch[j];i++;}Virus.ch[2*m+1]='\0'; //添加结束符号,很重要 没有的话 不能当作字符串处理for(i=0;i<m;i++) //依次取得每个长度为m 的病毒 DNA 环状字符串 temp{for (j=1; j<=m; j ++) temp.ch[j]=Virus.ch[i+j];temp.ch[m+1]='\0'; //添加结束符号flag=Index_BF (Person, temp, 1); //模式匹配if(flag) break; //匹配即可退出循环}//部分代码
算next数组
#include <iostream>
using namespace std;
#define MAXSIZE 255
int next1[MAXSIZE];
//报错next不明确是因为和std命名空间冲突了,它作为全局变量不行,所以改成next1
void get_next(char t[])
{char t2[MAXSIZE] = { '0' };//初始化 一个好习惯罢啦for (int m = 0; m < MAXSIZE - 1; m++){t2[m + 1] = t[m];if (t[m] == '\0')break;}//这一步 算是一个比照 int i = 1, j = 0;next1[1] = 0;while (i < strlen(t)){if (j == 0 || t2[i] == t2[j]){i++;j++;next1[i] = j;}else{j = next1[j];}}
}
好啦 接下来就是完全的代码 (bf算法 因为我们学校期末考试kmp考的少 哪天得空再试试
#include<iostream>
#include<string.h>
#include <fstream> //文件操作头文件
#define MAXSIZE 255 //串的最大长度
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
using namespace std;typedef struct{ char ch[MAXSIZE+1]; //字符串的结尾为‘/0’ int length; //串的当前长度
}SString; typedef struct{ char Results[MAXSIZE+1];//存放检测结果
}Detection;
同样的把结构体和宏定义放在头文件
函数实现:
#include"virus.h"int Index_BF(SString S,SString T,int pos)
{int i,j;i=pos,j=0; //初始化while(i<S.length && j<T.length) //bf算法{if(S.ch[i]==T.ch[j]){i++;j++;} else{i=i-j+1;j=0;} }if (j >= T.length)return OK;//匹配成功else return ERROR; //匹配失败
}void Virus_detection(SString S[],SString T[],int num,Detection detection[])
{SString Person,Virus,temp;int i,j,m,flag,k=0;while(num--) //依次检测每对病毒 DNA 和人的 DNA 是否匹配{Person=S[k];Virus=T[k];flag=0; //用来标识是否匹配,初始为0, 匹配后为非0m=Virus.length; //病毒 DNA 序列的长度是 mfor(i=m, j=0; j<m; j++){Virus.ch[i++]=Virus.ch[j]; //将病毒字符串的长度扩大2倍}Virus.ch[2*m]='\0'; //添加结束符号for(i=0;i<m;i++) //依次取得每个长度为m 的病毒 DNA 环状字符串 temp{for (j=0; j<m; j++) temp.ch[j]=Virus.ch[i+j];temp.ch[m]='\0'; //添加结束符号temp.length=Virus.length;flag=Index_BF (Person, temp, 0); //模式匹配if(flag)break; //匹配即可退出循环}if(flag) strcpy(detection[k].Results,"YES");else strcpy(detection[k].Results,"NO");k++;}
}int main()
{SString person[MAXSIZE],virus[MAXSIZE];int num;ifstream fin("bingdu.txt");ofstream fout("jieguo.txt");fin>>num;Detection detection[MAXSIZE];for(int i=0;i<num;i++){fin>>virus[i].ch>>person[i].ch;}Virus_detection(person,virus,num,detection);for(int i=0;i<num;i++){fout<<virus[i].ch<<" "<<person[i].ch<<" "<<detection[i].Results<<endl;}return 0;
}
个人觉得要写好这个代码需要:
函数形参为数组怎么传址
文件操作
bf算法
结构体赋值和判断相等
串还有个作业 是文本编辑器的