蓝桥杯 2019-8 滑动窗口之人物相关性分析

本文介绍如何通过编程解决小说中人物Alice和Bob的亲密时刻计数问题,当他们之间的字符数不超过K时算作同时出现。利用Java实现,通过遍历字符串和维护两个向量记录出现位置,找出满足条件的共同出现次数。
摘要由CSDN通过智能技术生成

题目:
第八题:人物相关性分析
题目描述

小明正在分析一本小说中的人物相关性。他想知道在小说中 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 个字符。
注意:
Alice 和 Bob 是大小写敏感的,alice 或 bob 等并不计算在内。
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
分别在左右设置l,r作为标记点,
遍历一次字符串记录下Alice和Bob出现的下标,然后从Alice第一次出现的位置开始搜索,对于l,要找到Bob的位置第一次距离Alice小于k的位置,然后记录;对于r,找到Bob的位置第一次距离Alice大于k的位置。注意我把Alice和Bob的下标存在vector里面,所以Alice[l]中l表示的是第几个Alice,而Alice[l]表示的是Alice第l次出现在字符串中的下标。所以在这个Alice中,与它同时出现的Bob个数是r - l;之后再找下一个Alice,r和l还是从上次的开始搜索,因为这个Alice肯定下标比上一个大,那么左边的Bob与上一个的差距大于k的,肯定与这个也大于k,所以就不用再判断了,接着上一次左边的位置向右判断就行,右边也是同理,右边的Bob与上一个的差距小于k的,肯定与这个也小于k,所以接着上一次右边的位置向右判断就行。
在这里插入图片描述

import java.util.Scanner;
import java.util.Vector;

public class okt8人物相关性分析 {
	public static void main(String[] args) {
		f2();
	}

	private static void f2() {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		int k = scanner.nextInt();
		scanner.nextLine();
		String string = scanner.nextLine();
		Vector<Integer> A = new Vector<Integer>();
		Vector<Integer> B = new Vector<Integer>();
		for (int i = 0; i < string.length(); i++) {
			if (string.charAt(i) == 'A') {
				if (string.substring(i, i + 6).equals("Alice ") || string.substring(i, i + 6).equals("Alice.")) {
					A.add(i);
					// System.out.println(i + string.substring(i, i + 6));
					i += 5;

				}
			}
			if (string.charAt(i) == 'B') {
				if (string.substring(i, i + 3).equals("Bob ") || string.substring(i, i + 4).equals("Bob.")) {
					B.add(i);
					// System.out.println(i);
					i += 3;
				}
			}
		}
		int l = 0;
		int r = 0;
		long ans = 0;

		for (int i = 0; i < A.size(); i++) {
			// System.out.println(A.get(i));
			// System.out.println(B.get(i));
			while (l < B.size() && B.get(l) < A.get(i) - k - 3)
				l++;
			while (r < B.size() && B.get(r) <= A.get(i) + k + 5)
				r++;
			ans += r - l;
			// System.out.println(l + " " + r);
		}
		System.out.println(ans);
	}
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值