试题 H: 人物相关性分析
【问题描述】
小明正在分析一本小说中的人物相关性。他想知道在小说中 Alice 和 Bob
有多少次同时出现。
更准确的说,小明定义 Alice 和 Bob“同时出现”的意思是:在小说文本
中 Alice 和 Bob 之间不超过 K 个字符。
例如以下文本:
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
假设 K = 20,则 Alice 和 Bob 同时出现了 2 次,分别是”Alice and Bob”
和”Bob. Alice”。前者 Alice 和 Bob 之间有 5 个字符,后者有 2 个字符。
注意:
1. Alice 和 Bob 是大小写敏感的,alice 或 bob 等并不计算在内。
2. Alice 和 Bob 应为单独的单词,前后可以有标点符号和空格,但是不能
有字母。例如 Bobbi 並不算出现了 Bob。
【输入格式】
第一行包含一个整数 K。
第二行包含一行字符串,只包含大小写字母、标点符号和空格。长度不超
过 1000000。
【输出格式】
输出一个整数,表示 Alice 和 Bob 同时出现的次数。
【样例输入】
20
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
【样例输出】
2
【评测用例规模与约定】
对于所有评测用例,1 ≤ K ≤ 1000000。
【代码】
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
// BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
Main main = new Main();
main.receiveData();
System.out.println(main.solve());
}
int k;
String txt;
byte[] site; // 利用下标表示Alice和Bob在字符串中的位置
void receiveData() {
Scanner reader = new Scanner(System.in);
k = reader.nextInt();
reader.nextLine();
txt = " "+reader.nextLine()+" "; // 去掉Alice和Bob位于字符串首或字符串尾时的特殊性
site = new byte[txt.length()];
}
int solve() {
char[] txtCh = txt.toCharArray(); // 判断查找到的Alice和Bob前后字符是否为非字母
int k = -1;
while ((k = txt.indexOf("Alice",k + 1)) != -1) {
// 若Alice前后字符非字母,则在site中记录其位置
if (!('A' <= txtCh[k-1] && txtCh[k-1] <= 'Z' && 'a' <= txtCh[k-1] && txtCh[k-1] <= 'z')
&& !('A' <= txtCh[k+1] && txtCh[k+1] <= 'Z' && 'a' <= txtCh[k+1] && txtCh[k+1] <= 'z')) {
site[k] = 1;
}
}
k = -1;
while ((k = txt.indexOf("Bob",k + 1)) != -1) {
// 若Bob前后字符非字母,则在site中记录其位置
if (!('A' <= txtCh[k-1] && txtCh[k-1] <= 'Z' && 'a' <= txtCh[k-1] && txtCh[k-1] <= 'z')
&& !('A' <= txtCh[k+1] && txtCh[k+1] <= 'Z' && 'a' <= txtCh[k+1] && txtCh[k+1] <= 'z')) {
site[k] = 2;
}
}
int ans = 0;
// 查找Alice位置前后是否有Bob,有则+1
for (int i = 0; i < site.length; i++) if (site[i] == 1) {
int l = i - this.k - 3 > 0 ? i - this.k - 3 : 0; // 最小为0
int r = i + this.k + 5 < site.length ? i + this.k + 5 : site.length; // 最大为site.length
for (int j = l; j <= r; j++) {
if (site[j] == 2) ans++;
}
}
return ans;
}
}