前言
回忆版,仅供学习。
2021.3.18
一、两名字的缘分值
题目 :缘分值定义:两个名字(字符串)通过删除字符,使得留下的子串一直,所删除的ASCII之和最小值为两个名字的缘分值。
输入描述:输入两行名字,上下两行对应位置名字进行缘分值计算。2<=每个名字的长度<=10,2<=每个名字的<=20
输出描述:输出总缘分值。
样例输入
Zhang San
Zhan Ai
样例输出
563
说明:
第一组名字,删除‘g’使其相等 ASCII =103,第二组都不同全要删掉,ASCII=290+170=460,总操作数103+460=563。
分析:
- 动态规划来算每两个字符串的最小删除和啊,子序列问题
- 结果相加
- ac了一部分,不知道哪地方没过
package com.mianshi;
import java.util.Arrays;
public class Main {
/*请完成下面这个函数,实现题目要求的功能
当然,你也可以不按照下面这个模板来作答,完全按照自己的想法来 ^-^
******************************开始写代码******************************/
static int calcSimilarity(String name1, String name2) {
String[] name1char = name1.split(" ");
String[] name2char = name2.split(" ");
int len1 = name1char.length;
int len2 = name2char.length;
int max_len = Math.max(len1,len2);
int res_all = 0;
for(int i =0 ; i< max_len ;i++){
String str1 = " ";
String str2 = " ";
if(i<len1){
str1 = name1char[i];
}
if(i<len2){
str2 = name2char[i];
}
int[][] memory = new int[str1.length()][str2.length()];
for(int[] row : memory){
Arrays.fill(row,-1);
}
int res_i = LCSdp(str1, 0, str2, 0,memory);
res_all+=res_i;
}
return res_all;
}
static public int LCSdp(String s1,int i,String s2,int j,int[][] memory){//找两个的LCS
int shu =0;//记录操作数
//base case
if(s1.length() == i){
for(;j<s2.length();j++){
shu+=s2.charAt(j);
}
return shu;
}
if(j == s2.length()){
for(;i<s1.length();i++){
shu+=s1.charAt(i);
}
return shu;
}
if(memory[i][j]!=-1){
return memory[i][j];
}
if(s1.charAt(i) == s2.charAt(j)){//相等不操作
memory[i][j] = LCSdp(s1,i+1,s2,j+1,memory);
}else{
memory[i][j] = Math.min(s1.charAt(i)+LCSdp(s1,i+1,s2,j,memory),s2.charAt(j)+LCSdp(s1,i,s2,j+1,memory));
}
return memory[i][j];
}
/******************************结束写代码******************************/
public static void main(String[] args){
Main a = new Main();
int sum = a.calcSimilarity("Zhang San","Zhan Ai");
System.out.println(sum);
}
}
二、AC自动机
没接触过,蒙蔽状态,用了HashMap<String,HashSet< String >>做字符匹配好像有问题。