华为OD刷题C卷 - 每日刷题 6 (求字符串中所有整数的最小和、求满足条件的最长子串的长度)

73 篇文章 0 订阅
37 篇文章 1 订阅

两段代码分别解决了两个字符串处理的问题,下面是对它们的概述:

1、(求字符串中所有整数的最小和):

这段代码是解决“求字符串中所有整数的最小和”的问题。它提供了一个Java类Main,其中包含一个方法getMinSum,该方法接收一个字符串str,并返回字符串中包含的所有整数的最小和。

代码首先将字符串转换成字符数组,然后使用一个Stack<BigInteger>来存储遇到的数字。由于题目要求处理的整数没有长度限制,因此使用BigInteger来处理大数。

在遍历字符串的过程中,代码会根据字符是数字还是符号(+-)来更新当前数字或将其压入栈中。如果遇到负号,则将当前数字乘以-1后压入栈中。如果遇到非数字字符(除了数字和加减号之外的字符),则将当前符号设置为+,并将数字重置为0

最后,使用stream().reduce()方法对栈中的所有数字进行求和操作,并返回结果。

2、(求满足条件的最长子串的长度):

这段代码是解决“求满足条件的最长子串的长度”的问题。它提供了一个Java类Main,其中包含一个方法getResult,该方法接收一个字符串s,并返回满足条件的最长子串的长度。

满足条件的子串要求只包含一个字母(a~z, A~Z),其余部分必须是数字。字母可以在子串中的任意位置。

代码使用双指针leftright来遍历字符串。同时使用一个LinkedList<Integer>来记录字母的索引。当遇到字母时,将其索引压入栈中,并更新字母的计数。如果字母计数超过1,则将左指针移动到上一个字母的下一个位置,并将左指针之前的字母索引从栈中移除。

在遍历过程中,代码会更新满足条件的最长子串长度maxLen。最后,如果整个字符串中没有字母,则返回-1;否则返回计算得到的最长子串长度。

package OD149;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Stack;

/**
 * @description 求字符串中所有整数的最小和
 * @level 7
 * @score 100
 */

/**
 * 题目描述
 * 输入字符串s,输出s中包含所有整数的最小和。
 * <p>
 * 说明:
 * <p>
 * 字符串s,只包含 a-z A-Z ±
 * <p>
 * 合法的整数包括
 * <p>
 * 1)正整数:一个或者多个0-9组成,如 0 2 3 002 102
 * <p>
 * 2)负整数:负号 – 开头,数字部分由一个或者多个0-9组成,如 -0 -012 -23 -00023
 * <p>
 * 输入描述
 * 包含数字的字符串
 * <p>
 * 输出描述
 * 所有整数的最小和
 */
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //读取
        String str = sc.nextLine();
        System.out.println(getMinSum(str));
    }

    //读取字符串中的最小整数和 数字没有限制长度,要用大数处理
    public static BigInteger getMinSum(String str) {
        //字符串str,只包含 a-z A-Z ±
        char[] chars = str.toCharArray();
        int n = chars.length;
        //初始化数字
        BigInteger number = new BigInteger("0");
        //初始化符号
        char sign = '+';

        //存放操作数,正数单个加,负数整体加
        Stack<BigInteger> stack = new Stack<>();

        for (int i = 0; i < n; i++) {
            //因为要找最小和,遇到正号直接加,遇到负号把后面数字拼起来加
            char c = chars[i];

            //遇到数字,判断正数直接入栈、负数整体入栈
            if (Character.isDigit(c)) {
                if (sign == '+') {
                    stack.push(new BigInteger(String.valueOf(c)));
                } else {
                    //拼数字
                    number = number.multiply(new BigInteger("10")).add(new BigInteger(String.valueOf(c)));
                }
            }

            //不是数字,则判断是符号 输入控制只有a-z A-Z ±
            if (!Character.isDigit(c) || i == n - 1) {
                //如果符号为-,把前面整体入栈
                if (sign == '-') {
                    //把前面整体入栈
                    stack.push(number.multiply(new BigInteger("-1")));
                }
                //刷新符号 遇到字母的话刷新为+号
                sign = c == '-' ? '-' : '+';
                //刷新数字
                number = new BigInteger("0");
            }
        }
        //返回stack求和
        return stack.stream().reduce(BigInteger::add).orElse(new BigInteger("0"));
    }
}

package OD153;

import java.util.LinkedList;
import java.util.Scanner;

/**
 * @description 求满足条件的最长子串的长度
 * @level 6
 * @score 100
 */

/**
 * 题目描述
 * 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度,字符串本身是其最长的子串,子串要求:
 * <p>
 * 1、 只包含1个字母(a~z, A~Z),其余必须是数字;
 * <p>
 * 2、 字母可以在子串中的任意位置;
 * <p>
 * 如果找不到满足要求的子串,如全是字母或全是数字,则返回-1。
 * <p>
 * 输入描述
 * 字符串(只包含字母和数字)
 * <p>
 * 输出描述
 * 子串的长度
 */
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //读取输入字符串
        String str = sc.nextLine();
        System.out.println(getResult(str));

    }

    //寻找只包含一个数字的最长子串长度,没有则返回-1
    public static int getResult(String s) {
        int n = s.length();
        //存放数字的索引
        //双指针:从0开始,右指针往右移动,遇到字母就+1,并记录下标,左指针移动到上一个字母下标+1处
        int left = 0;
        int right = 0;
        int maxLen = -1;
        LinkedList<Integer> lastLetter = new LinkedList<>();
        int countLetter = 0;
        while (right < n) {
            char c = s.charAt(right);
            //如果是字母,则记录下标
            if (Character.isLetter(c)) {
                countLetter++;
                lastLetter.add(right);
                //如果超过1个字母,则左指针移动
                if (countLetter > 1) {
                    left = lastLetter.removeFirst() + 1;
                    countLetter--;
                }
                if (left == right) {
                    right++;
                    continue;
                }
            }
            //此时left到right之间一定最多一个字母
            maxLen = Math.max(maxLen, right - left + 1);
            right++;
        }
        //如果没有字母,则返回-1
        if (countLetter == 0) {
            return -1;
        }
        //否则返回maxLen
        return maxLen;
    }
}
  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值