题目要求
给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子的长度,字符串本身是其最长的子串,子串要求:
- 只包含1个字母(az,AZ),其余必须是数字;
- 字母可以在子串中的任意位置;
如果找不到满足要求的子串,如全是字母或全是数字,则返回-1。
输入描述
字符串(只包含字母和数字)
输出描述
子串的长度
示例1
输入:
abC124ACb
输出:
4
说明:
满足条件的最长子串是C124或者124A,长度都是4
示例2
输入:
a5
输出:
2
说明:
字符串目身就是满足条件的子串,长度为2
示例3
输入:
aBB9
输出:
2
说明:
满足条件的子串为B9,长度为2
示例4
输入:
abcdef
输出:
-1
说明:
没有满足要求的子串,返回-1
解题思路
- 定义一个正则表达式模式,用于匹配包含至少一个字母且之间可能包含数字的字符串。
- 如果不会,则可以在遍历字符串的时候加以判断
- 从左往右遍历字符串,连续的两个字节为不全是字母为遍历条件
- 连续的两个字节有两种情况
- 第一个为字母,第二个为数字,则满足的条件为后续都为数字
- 第一个为数字,则后续的字节最多只能拼接一个字母
代码
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;
}
}