试题 H: 人物相关性分析【第十届蓝桥杯 省赛 Java B组】

试题 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;
	}
}

你可能感兴趣的:(算法,蓝桥杯,算法,字符串,java)