求满足条件的最长子串的长度

题目要求

给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子的长度,字符串本身是其最长的子串,子串要求:

  1. 只包含1个字母(az,AZ),其余必须是数字;
  2. 字母可以在子串中的任意位置;

如果找不到满足要求的子串,如全是字母或全是数字,则返回-1。

输入描述

字符串(只包含字母和数字)

输出描述

子串的长度

示例1

输入:
abC124ACb

输出:
4

说明:
满足条件的最长子串是C124或者124A,长度都是4

示例2

输入:
a5

输出:
2

说明:
字符串目身就是满足条件的子串,长度为2

示例3

输入:
aBB9

输出:
2

说明:
满足条件的子串为B9,长度为2

示例4

输入:
abcdef

输出:
-1

说明:
没有满足要求的子串,返回-1

解题思路

  1. 定义一个正则表达式模式,用于匹配包含至少一个字母且之间可能包含数字的字符串。
    • 如果不会,则可以在遍历字符串的时候加以判断
  2. 从左往右遍历字符串,连续的两个字节为不全是字母为遍历条件
  3. 连续的两个字节有两种情况
    1. 第一个为字母,第二个为数字,则满足的条件为后续都为数字
    2. 第一个为数字,则后续的字节最多只能拼接一个字母

代码

package com.example.demo;

import java.util.Scanner;

/**
 * @Desc: 求满足条件的最长子串的长度
 * 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子的长度,字符串本身是其最长的子串,子串要求:
 * 只包含1个字母(az,AZ),其余必须是数字;
 * 字母可以在子串中的任意位置;
 * 如果找不到满足要求的子串,如全是字母或全是数字,则返回-1。
 * 输入:
 * abC124ACb
 * 输出:
 * 4
 * 说明:
 * 满足条件的最长子串是C124或者124A,长度都是4
 * abC12a43ACb
 * @Auther:chenLing
 * @Date: 2024/7/16 11:40
 */
public class Test21 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        sc.close();
        System.out.println(getMaxStrLength(str));
    }

    private static int getMaxStrLength(String str) {
        //^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$
        //分开来注释一下:
        //^ 匹配一行的开头位置
        //(?![0-9]+$) 预测该位置后面不全是数字
        //(?![a-zA-Z]+$) 预测该位置后面不全是字母
        //[0-9A-Za-z] 由数字或这字母组成
        //$ 匹配行结尾位置
        // 字符串是否包含数字或者字母
        String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]*$";
        if (!str.matches(regex)) {
            return -1;
        }
        char[] chars = str.toCharArray();
        int right = 0;
        int max = 0;
        int length = str.length();
        for (int left = 0; left < length - 1; left++) {
            // 判断当前位移起点剩余字段,如果小于匹配的最大字符串,则终止
            if (length - left < max) {
                break;
            }
            // 连续两个字符串是字母,则位移
            right = left + 1;
            if (Character.isLetter(chars[left]) && Character.isLetter(chars[right])) {
                continue;
            }
            // 第一个字符是数字
            if (Character.isDigit(chars[left])) {
                // 计算字母的数量
                int temp = 0;
                while (right < length) {
                    if (!Character.isDigit(chars[right])) {
                        temp++;
                    }
                    if (temp > 1) {
                        break;
                    }
                    right++;
                }
            } else {
                // 第一个字符是字母
                // right一直递增
                while (right < length && Character.isDigit(chars[right])) {
                    right++;
                }
            }
            // 如果需要获取满足条件的字符串,则可以在此收集
            if (right - left > max) {
                max = right - left;
            }
        }
        return max;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值