华为OJ——字符串运用-密码截取

题目描述

       Catcher 是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

  • 输入描述:

    输入一个字符串

  • 输出描述:

    返回有效密码串的最大长度

  • 示例1

    输入
    ABBA
    输出
    4

  • 动态转移方程为:

    • 如果xi == yj, 则 c[i][j] = c[i-1][j-1]+1
    • 如果xi != yj, 那么c[i][j] = 0

代码实现

  • 方法一(内存过大)

    注意:问题在于牛客网上提示内存超过限制,主要原因:定义二维数组时,若字符串长度过长,容易超内存限制,有待优化。

package cn.c_shuang.demo32;

import java.util.Scanner;
/**
 * 字符串运用-密码截取
 * @author Cshuang
 *
 */

public class Main {
    public static void main(String[] args) {
        Scanner in =new Scanner(System.in);
        while(in.hasNext()){
            String s=in.nextLine();
            String sRever=new StringBuilder(s).reverse().toString();
            //字符串与字符串反转后进行比较
            System.out.println(findMaxCode(s,sRever));
        }
        in.close();
    }

    private static int findMaxCode(String a, String b) {
        int aLen=a.length()+1;
        int bLen=b.length()+1;//子所以要限制长度+1,方便c[0][0]
        //事实上真正计数的从c[1][1]开始
        int[][] c=new int[aLen][bLen];
        int max=0;
        for (int i = 1; i < aLen; i++) {
            for (int j = 1; j < bLen; j++) {
                if(a.charAt(i-1)==b.charAt(j-1)){
                    c[i][j] = c[i-1][j-1]+1;  
                }else{
                    c[i][j]=0;
                }
                if(c[i][j]>max){
                    max=c[i][j];
                }
            }
        }
        return max;
    }
}
  • 方法二(优解):

    思路:将字符串任意一点当做中心,来上下增减,来判断长度,其主要分为奇对称和偶对称情况。

package cn.c_shuang.demo32_1;

import java.util.Scanner;

/**
 * 字符串运用-密码截取
 * 
 * @author Cshuang
 * 
 * 从字符的第二个字符开始遍历,分别将当前遍历的字符作为回文串的中心词,
 * 分为ABA和ABBA两种情况,算出每个字符作为中心词时最长回文串长度。
 */

public class Main {
    public static void main(String[] args) {
        Scanner in =new Scanner(System.in);
        while(in.hasNext()){
            String str=in.nextLine();
            char[] ch=str.toCharArray();
            int length=str.length();
            int max=1;
            for(int i=1;i<length;i++)
            {
                int j;
                //对应ABA的奇对称情况
                //对于ch[i-j]需限制i-j>=0
                //对于ch[i+j]需限制i+j<length
                for(j=1;(i-j>=0)&&((i+j)<length)&&ch[i-j]==ch[i+j];j++);
                if(2*j-1>max)
                {
                    max=2*j-1;
                }
                //对应ABBA对称的情况(针对偶对称情况)
                for(j=0;(i-1-j>=0)&&((i+j)<length)&&ch[i-1-j]==ch[i+j];j++);
                if(2*j>max)
                {
                    max=2*j;
                }
            }
            System.out.println(max);
        }
        in.close();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值