头文件(tou.h):
void get_next(char T[], int next[]);
int Index_KMP(char S[], char T[]);
void move1(char a[]);
void transform(char a[]);
void Judge(char S[], char T[]);
void gcd(char a[]);
头文件中函数的实现(tou.cpp):
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include"tou.h"
void move1(char a[]) { //将数组a整体向后移动一位,让a[0]失效
for (int i = strlen(a); i > 0; i--) {
a[i] = a[i - 1];
}
}
void transform(char a[]) { //将数组头(a[1])调到数组尾,数组整体向前进一位
int length = strlen(a)-1;
char head = a[1];
for (int i = 1; i < length; i++) {
a[i] = a[i + 1];
}
a[length] = head;
}
void gcd(char a[]) { //颠倒数组元素的顺序(数组下标从1开始)
int length = strlen(a) - 1;
for (int i = 1; i < 1 + length / 2; i++) {
char temp = a[i];
a[i] = a[length + 1 - i];
a[length + 1 - i] = temp;
}
}
void get_next(char T[], int next[]) { //根据模式串设置好next[]数组中对应的值
int length_T = strlen(T)-1;
int i = 1, j = 0;
next[1] = 0;
while (i < length_T) {
if (j == 0 || T[i] == T[j]) {
i++, j++;
next[i] = j;
}
else
j = next[j];
}
}
int Index_KMP(char S[], char T[]) { //KMP算法。在主串S中找 是否有与模式串T相等的串
int next[100] = {};
get_next(T, next);
int length_S = strlen(S)-1;
int length_T = strlen(T)-1;
int i = 1, j = 1;
while (i <= length_S && j <= length_T) {
if (j == 0 || S[i] == T[j]) {
i++, j++;
}
else j = next[j];
}
if (j > length_T) return 1;
else return 0;
}
void Judge(char S[], char T[]) { //判断人DNA是否感染环状病毒DNA
int length_T = strlen(T) - 1;
int i = length_T;
while (i) {
transform(T);
if(Index_KMP(S,T)) break;
gcd(T); //颠倒模式串重新判断
if (Index_KMP(S, T)) break;
gcd(T); //恢复模式串
i--;
}
if (i) printf("是否感染:YES");
else printf("是否感染:NO");
}
主函数(ceshi1.cpp):
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include"tou.h"
int main() {
while (1) {
char T[100] = {}; //模式串(病毒DNA)
char S[100] = {}; //主串(人DNA)
printf("请输入 病毒的DNA序列 和 人的DNA序列:\n");
scanf("%s%s", T, S);
if (T[0] == '0' && S[0] == '0') break; //结束条件
move1(S), move1(T);
Judge(S, T);
printf("\n\n");
}
return 0;
}
测试结果: