试题B:网站扩张
这道题我用到了递归算法,代码含义都下边代码的注释里,不再多做解释。
代码实现
//递归方法
public int people(int n) {//n为天数
int b=1;//用户个数
for (int i = 1; i <= n; i++) {
if(n>7) {//若n<=7,即前七天用户一直是一个,七天之后才开始改变
/*
* 由题可知在此用户使用前七天之后的每一个七天的第一天,第四天,和第七天都会增加一个用户,
* 这里当增加用户时b+1且进行递归,递归中的天数为从这个新用户使用开始到n的天数而不是n
*/
if(i%7==1||i%7==4||i%7==0) {
b += 1;
people(n-i);
}
}
}
return b;
}
试题C:基因配对
这道题应该用到字符串的模式匹配,由于普通的模式匹配算法在字符串过长时运行时间长,为了追求快速匹配,我这里用了模式匹配的KMP算法。下面是我学习KMP算法过程中参考的视频:
字符串在Java中是不可变的,但是为了把模式串的ATCG替换为TAGC,可以使用StringBuilder:
StringBuilder strb = new StringBuilder(S);
strb.setCharAt(i, 'A');
代码实现
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String L=scanner.nextLine();//主串
String S=scanner.nextLine();//模式串
//因为是基因配对,所以先把模式串的ATCG改为TAGC
StringBuilder strb = new StringBuilder(S);
for (int i = 0; i < S.length(); i++) {
if (S.charAt(i)=='A') {
strb.setCharAt(i, 'T');
}else if (S.charAt(i)=='T') {
strb.setCharAt(i, 'A');
}else if (S.charAt(i)=='C') {
strb.setCharAt(i, 'G');
}else if (S.charAt(i)=='G') {
strb.setCharAt(i, 'C');
}
}
int index=KMP(L, strb);//调用KMP算法方法得到索引
System.out.println(index+1);//输出位置
}
//KMP算法方法
public static int KMP(String L,StringBuilder subStr) {
//计算next数组
int[]next=getNext(subStr);
//定义一个指针,用于指向主串中的第一个字符
int x=0;
//定义一个指针,用于指向模式串中的第一个字符
int y=0;
//循环实现字符串的匹配操作
while (x<L.length()&&y<subStr.length()) {
if(y==-1||L.charAt(x)==subStr.charAt(y)) {
x++;
y++;
}else {
y=next[y];
}
}
if(y==subStr.length()) {
return x-y;
}else {
return -1;
}
}
//得到next数组的方法
public static int[] getNext(StringBuilder subStr) {
//定义一个next数组
int[] next=new int[subStr.length()];
//设置next数组的第一个元素值为-1
next[0]=-1;
//设置两个元素y和len,y指匹配失败时模式串的索引,len指当前最大前后缀长度
int y=0,len=-1;
//定义一个循环,用于计算next数组
while (y<subStr.length()-1) {
if (len==-1||subStr.charAt(y)==subStr.charAt(len)) {
y++;
len++;
next[y]=len;
}else {
len=next[len];
}
}
return next;
}