华为OD机试:21 字符串解密

package a_od_test;

import java.util.*;

/*
字符串解密
知识点数组字符串排序Q
时间限制:1s空间限制:256MB限定语言:不限
题目描述:
给定两个字符串string1和string2。
string1是一个被加扰的字符串。string1由小写英文字母('a'~'z)和数字字符(0'~'9)组成,而加扰字符串由'0'~'9'、'a'~'f'组成。
string1里面可能包含0个或多个加扰子串,剩下可能有0个或多个有效子串,这些有效子串被加扰子串隔开。
string2是一个参考字符串,仅由小写英文字母('a'~'z')组成。
你需要在string1字符串里找到一个有效子串,这个有效子串要同时满足下面两个条件:
(1)这个有效子串里不同字母的数量不超过且最接近于string2里不同字母的数量,即小于或等于string2里不同字母的数量的同时且最大。
(2)这个有效子串是满足条件(1)里的所有子串(如果有多个的话)里字典
序Q最大的一个。
如果没有找到合适条件的子串的话,请输出"Not Found"
示例:
输入字符串string1为"thisisanewday111 forme",
输入字符串string2为"good"。
string1里有效子串和加扰子串分割后可表示为:"thisis"+"a"+"n"+"e"+"w"+"da"+"y"+"111f"+"orm"+"e",
去除加扰子串("a"、"e"、"da"、"111f"、"e")后的有效子串候选为("thisis'”,"n","w","y","orm")。
输入字符串string2里不同字母的数量为3('g、'o'、'd),从有效子串候选里可以找出“orm"满足要求,
其不同字母的数量为3,最接近于string2不同字母的数量。
输入描述:
input string1 input string2
说明:输入为两个字符串,第1行是题目里的string1(被加扰的字符串),第2行是题目里的string2(参考字符串)
输出描述:
output string
说明:输出为一个字符串(有效字符串)
补充说明:
输入字符串string1的长度在1~100000之间,string2的长度在1~500之间
示例1
输入:
123admyffc79pt ssyy
输出:
pt
说明:
将输入字符串1里的加扰子串"123ad"、"c79"去除后得到有效子串序列:"my"、"pt",
其中"my"里不同字母的数量为2(有'm和'y两个不同字母),"pt"里不同字母的数量为2(有和't两个不同字母)同时字典序最大。
示例2
输入:
123admyffc79ptaagghi2222smeersst88mnrt ssyyfgh
输出:
mnrt
说明:
将输入字符串1里的加扰子串"123ad"、fc79"、"aa"、"2222""ee"、"88"去除后得到有效子串序列:"my"、"pt"、"gghi"、"sm"、"rsst"、"mnrt";
输入字符串2里不同字母的数量为5(有s、y、f、g、h'5个不同字母)。
可得到最终输出结果为"mnt",其不同字母的数量(为4)最接近于"ssyyfgh"里不同字母的数量,其他有效子串不同字母的数量都小于"mnrt"。
示例3
输入:
abcmnq rt
输出:
Not Found
说明:
将输入字符串1里的加扰子串"abc"去除后得到有效子串序列:"mnq";输入字符串2里不同字母的数量为2(有'、t两个不同的字母)。
可得到最终的输出结果为"Not Found",没有符合要求的有效子串,因有效子串的里不同字母的数量(为3),大于输入字符串2里的不同字母的数量
解题思路:
根据题意:
string1的子串要求:1、只包含字母g~z
2、且子中不同字母的数量小于等于string2中的不同字母数量
求字符串中不同字母数量可以使用set,set可以去重,set的长度则为不同字母的数量。
 */
public class Main21 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] split = sc.nextLine().split(" ");
        String string1 = split[0];
        String string2 = split[1];
        ArrayList<String> result = new ArrayList<>();
        String temp = "";
        int len2 = diffCharLenth(string2);
        int max = 0;
        for (int i = 0; i < string1.length(); i++) {
            char c = string1.charAt(i);
            //f-z为有效字符
            if (c > 'f' && c < 'z') {
                temp += c;
                //处理最后一个字符
                if (i == string1.length() - 1) {
                    int len1 = diffCharLenth(temp);
                    if (len1 <= len2) {
                        //当前子串长度大于列表中的最大长度,则清空列表
                        if (len1 >= max) {
                            result.clear();
                            //最接近对比字符串长度
                            max = Math.max(len1, max);
                        }
                        result.add(temp);
                    }
                }
            } else {
                if ("".equals(temp)) continue;
                int len1 = diffCharLenth(temp);
                //有效字符串不同字符个数要小于等于对比字符串
                if (len1 <= len2) {
                    //当前子串长度大于列表中的最大长度,则清空列表
                    if (len1 >= max) {
                        result.clear();
                        //最接近对比字符串长度
                        max = Math.max(len1, max);
                    }
                    result.add(temp);
                }
                //tmp置为空
                temp = "";
            }
        }
        Collections.sort(result);
        System.out.println(result.size() == 0 ? "Not Found" : result.get(result.size() - 1));
    }

    /**
     *
     * @param str 传入字符串
     * @return    返回不同字符的个数
     */
    public static int diffCharLenth(String str) {
        HashSet<Character> set = new HashSet<>();
        for (char c: str.toCharArray()) {
            set.add(c);
        }
        return set.size();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值