问题描述
代码实现
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.TreeMap;
/**
* 试题H:人物相关性分析
8
Bob Alice sdf Bob Alice hgdgBob Alice gasdBob Alice Bob Alice asd BobAlice
*
*/
public class Correlation {
static Scanner sc = new Scanner(System.in);
static int K = Integer.parseInt(sc.nextLine());
static String str = sc.nextLine();
public static void main(String[] args) {
judge();
toMap(calculate(str,"Alice"), calculate(str,"Bob"));
}
/**
* 首先判断字符串是否符合最低要求
*/
public static void judge() {
if(str.length()<9) {
// 最简的情况"Alice Bob",至少有 9 个英文字母
System.out.println(0);
System.exit(0);
}else if(!str.contains("Alice") || !str.contains("Bob")) {
// 两个名字至少都包含一个
System.out.println(0);
System.exit(0);
}
}
/**
* 此方法计算出 name 在句子中的位置
* @param s 英文句子
* @param name 人物名称
* @return list 保存 人物name 在 英文句子s 的位置
*/
public static List<Integer> calculate(String s,String name) {
List<Integer> list = new ArrayList<Integer>();
int index = 0,prefix = 0,suffix = 0;
while(index < s.length() && index>=0) {
index = s.indexOf(name);
s = s.substring(index+name.length(), s.length());
suffix += index+name.length();
prefix = suffix-name.length()-1;
// 单词的前后缀字符正则判断
if(prefix < 0) {
// 如果name为句子的第一个单词,则只需判断后缀是否为标点或者空格
if(str.substring(suffix,suffix+1).matches("[ \\p{P}]")) {
list.add(prefix+1);
}
}else if(prefix == str.length()-name.length()-1) {
// 如果name为句子的最后一个单词,则只需判断前缀是否为标点或者空格
if(str.substring(prefix,prefix+1).matches("[ \\p{P}]")) {
list.add(prefix+1);
break;
}
}else if(str.substring(prefix,prefix+1).matches("[ \\p{P}]")) {
// 如果name在句子中间
if(str.substring(suffix,suffix+1).matches("[ \\p{P}]")) {
list.add(prefix+1);
}
}
}
return list;
}
/**
* 将两个list的值分别存入TreeMap进行排序,最后再存入数组中(方便操作)
* @param list1
* @param list2
*/
public static void toMap(List<Integer> list1,List<Integer> list2) {
Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
while(!list1.isEmpty()) {
map.put(list1.remove(0), 0);
}while(!list2.isEmpty()) {
map.put(list2.remove(0), 1);
}
int size = map.size();
int[][] A = new int[size][2];
int n = 0;
for (Entry<Integer, Integer> entry : map.entrySet()) {
A[n][0] = entry.getKey();
A[n++][1] = entry.getValue();
}
// System.out.println(Arrays.deepToString(A));
int result = 0;
for(int i=0;i<size-1;i++) {
int T = K;
if(A[i][1] != A[i+1][1]) {
if(A[i][1] == 0) T+=5; else T+=3;
if(A[i+1][0]-A[i][0] <= T) {
result++;
}
}
}
// 最终结果
System.out.println(result);
}
}
样例输入
8
Bob Alice sdf Bob Alice hgdgBob Alice gasdBob Alice Bob Alice asd BobAlice
样例输出
5
解题思路
这个解题思路一开始想得有些复杂了
1、judge():先判断结果等于零的情况
(1)句子必须符合一种情况的最简句子是“Bob Alice”或者“Alice Bob”,其特点是必须至少有9个字符
(2)句子中至少必须同时存在“Bob“和”Alice”两个英文单词
2、calculate(s,name):计算出 人物name 在 句子s 中的位置
3、toMap(list1,list2):分别将两个calculate()计算之后的值存入TreeMap中,key存储name在s中的位置,TreeMap会默认排序,
value用于区分排序后 key 是哪个人物的,之后map存入二维数组中,最后遍历二维数组判断可得题解