day39—编程题

1.第一题

1.1题目

描述:
求字典序在 s1 和 s2 之间的,长度在 len1 到 len2 的字符串的个数,结果 mod 1000007。
注意:本题有多组输入
输入描述:
每组数据包涵s1(长度小于50),s2(长度小于50),len1(小于50),len2(大于len1,小于50)
输出描述:
输出答案

1.2思路

  1. 将s1和s2都拼接为len2长度,s1拼接’a’,s2拼接’z’+1
  2. 用s2的每一个字符减去s1的每一个字符并保存到数组中
  3. 将数组中的结果进行计算

1.3解题

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            StringBuffer s1 = new StringBuffer(sc.next());
            StringBuffer s2 = new StringBuffer(sc.next());
            int len1 = sc.nextInt();
            int len2 = sc.nextInt();
            //  将s1和s2都拼接为len2长度
            // s1拼接'a'
            for(int i = s1.length();i < len2;i++){
                s1.append('a');
            }
            // s2拼接'z'+1
            for(int i = s2.length();i < len2;i++){
                s2.append('z' + 1);
            }
            // 用s2的每一个字符减去s1的每一个字符并保存到数组中
            int[] arr = new int[len2];
            for(int i = 0;i < len2;i++){
                arr[i] = s2.charAt(i) - s1.charAt(i);
            }
            long ret = 0;
            // 将数组中的结果进行计算
            for(int i = len1;i <= len2;i++){
                for(int j = 0;j < i;j++){
                    // 等价于ret += arr[j] * 26 ^ (i-j-1)
                    ret += arr[j] * Math.pow(26,i - j - 1);
                }
            }
            System.out.println((ret - 1) % 1000007);
        }
    }
}

2.第二题

2.1题目

描述:
我们有两个字符串m和n,如果它们的子串a和b内容相同,则称a和b是m和n的公共子序列。子串中的字符不一定在原字符串中连续。
例如字符串“abcfbc”和“abfcab”,其中“abc”同时出现在两个字符串中,因此“abc”是它们的公共子序列。此外,“ab”、“af”等都是它们的字串。
现在给你两个任意字符串(不包含空格),请帮忙计算它们的最长公共子序列的长度。
输入描述:
输入包含多组数据
每组数据包含两个字符串m和n,它们仅包含字母,并且长度不超过1024
输出描述:
对应每组输入,输出最长公共子序列的长度

2.2思路

  1. 本题采用动态规划求解
  2. 定义一个数组保存最大的公共子串
  3. 如果str1的i-1与str2的j-1位置字符相等的情况,最长公共子串为dp[i-1][j-1]+1
  4. 如果不相等,则为其上一步的最大值

2.3解题

import java.util.*;
public class Main {
    // 求最长公共子序列
    private static int LCS(String str1,String str2){
        int mLen = str1.length();
        int nLen = str2.length();
        int[][] dp = new int[mLen + 1][nLen + 1];
        for(int i = 1;i <= mLen;i++){
            for(int j = 1;j <= nLen;j++){
                //如果str1的i-1与str2的j-1位置字符相等的情况,最长公共子串为dp[i-1][j-1]+1
                if(str1.charAt(i-1) == str2.charAt(j-1)){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }else{
                	// 如果不相等,则为其上一步的最大值
                    dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        return dp[mLen][nLen];
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String str1 = sc.next();
            String str2 = sc.next();
            int ret = LCS(str1,str2);
            System.out.println(ret);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值