人物相关性分析

人物相关性分析

题目及分析

问题描述】
小明正在分析一本小说中的人物相关性。他想知道在小说中 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。

分析题意:

  1. 注意输入格式,对scanner要做到换行输入
  2. 长度不超过100000,说明暴力枚举会超时
  3. 涉及判断前后均不为字母方法,以及字符串的截取操作
  4. 滑动窗口优化

源代码

package com.qustion;

import java.util.Scanner;

public class q6 {
    static  long result =0;
    static int K;
    static String text;
    static int length;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        K=scanner.nextInt();
        scanner.nextLine();
        text=scanner.nextLine();
        length=text.length();

        //保存Alice和Bob的位置
        int[]number1=new int[1000000];//数量要足够大
        int[]number2=new int[1000000];
        int count1=0;
        int count2=0;
        scanner.close();


        for (int x = 0; x < length; x++) {
            //判断并记录下二者的位置并保存在number1中,保证前后都不是字母
            if(!isletter(x-1)&&x+4<length&&!isletter(x+5)&& text.substring(x,x+5).equals("Alice")){
                number1[count1++]=x;
            }
            if (!isletter(x-1)&&x+2<length&&!isletter(x+3)&&text.substring(x,x+3).equals("Bob")){
                number2[count2++]=x;//在number2中记下Bob的位置
            }

        }
        if(count1==0||count2==0){
            result=0;
        }else {
            int right=0,left=0;
            for (int x=0;x<count1;x++){//滑动数组开始滑动

                while (number2[left]<number1[x]-3-K){//left不存在于左边时需移位,且小于则循环继续
                    left++;
                }
                while (number2[right+1]<=number1[x]+K+5){//right+1存在于右边时移位,相当于加一
                    right++;
                }
                if(right-left>=0)result+=right-left+1;
                /*
                while(right+1<count2 && number2[right+1]<=number1[x]+K+5)未越界且右边一个数在区间内右移动
				{
					right++;
				}
				while(number2[left]+3+K<number1[x])左边不存在数则向左移
				{
					left++;
				}
				result += right-left+1;
                 */
            }
            System.out.println(result);
        }


    }
    public  static boolean isletter(int index){//判断是否为空格或标点符号

        if (index<0||index>=length){
            return false;
        }
        char a=text.charAt(index);//传入下标并得到对应下标的值
        return (a>='a'&&a<='z')||(a>='A'&&a<='Z');
    }


}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值