获取两个字符串中最大相同字串(一)

题目

获取两个字符串中最大相同字串,比如:

  • str1 = “abcwerthelloyuiodef”,
  • str2 = “cvhellobnm”
  • 提示:
  • 将短的那个串,进行长度依次递减的字串与较长的字串进行比较
题解

这里先分析 两个字符串只有一个最大相同子串的情况:

(1)思路分析:

只有一个最大相同最子串的情况下:

---->跟找最大公约数的算法类似:先确定str1、str2哪个更短一下, 拿短的去比较深蓝色文字

比较的具体情况为:假设有:

  • str1 = “abcwerthelloyuiodef”,
  • str2 = “cvhellobnm”(length==10)


----利用string的contains(CharSequence s),判断maxstr中,是否包含每次的minstr(str2自己或者子串,具体的minstr是什么进行比对,取决于是哪一趟比较):

  • (1)整体的话,因为str2长度为10,则有10大轮的比较(每一轮结束minstr-1,即minstr的长度减少1)
  • (2)每一大轮中,具体的-1的情况也不太一样:
  • minstr的初值为str2:cvhellobnm
  • ①如果第一轮结束之后,contains()的返回值为false,将minstr的长度-1。
  • 完成length-1操作之后,对于下一次要进行contains()的minstr有2种情况:
  • cvhellobn 或者 vhellobnm
  • ②如果第二轮结束之后,contains()的返回值为false,将minstr的长度-1。
  • 在①的基础上,完成length-1操作之后,对于下一次要进行contains()的minstr有4种情况:
  • cvhellob、vhellobn 或者 vhellobn、hellobnm

  • 也即,每次进行length-1 的操作,有两种可能:
  • 从当前minstr的首部-1,或者从当前minstr的尾部-1
  • –>设置两个指针,来完成这个功能:
  • start、end

(2)实现主要功能的代码块:

/*
* 将短的那个串,进行长度依次递减的字串与较长的字串进行比较 外层循环控制的是:一共可以length-1进行多少次(第一次不进行-1,直接比较)
*/
			for (int i = 0; i < minString.length(); i++) {
				/*
				 * 因为 substring()的截取区间是左开右闭, 所以,end指针应该指向当前minstring字符串最后一个元素对应的char[]中的索引的后一个位置
				 * ---- 在这里,将length-1操作设置为:先减去尾部的长度为i的char,依次是倒数第二个...
				 * 也即,减去后的substring顺序为(从第一大轮开始):
				 * cvhellobnm-->cvhellobn--vhellobnm-->cvhellob--vhellobn(--cvhellob,出现过这种情况)--
				 * hellobnm-->...
				 */
				for (int start = 0, end = minString.length() - i; end <= minString.length(); start++, end++) {
					// 因为length-1 可能是从左侧划掉一个char,也可能是从右侧。
					// 并且,minstring与循环的控制条件有关,所以不应该将对于短的字符串的修改保留在minstring上
					String subString = minString.substring(start, end);
					if (maxString.contains(subString)) {
						/*
						 * 如果maxstring中包含当前的修改过后的minstring(也就是substring), 由于minstring是从大到小的范围找,
						 * 那么,此时得到的就是str1、str2的最大子串
						 */

						return subString;
					}
				}
			}
完整代码
public class MaxSimpleString {

	public static void main(String[] args) {
		
		String str1 = "abcwerthelloyuiodef";
		String str2 = "cvhellobnm";
		//造一个当前类的对象
		MaxSimpleString mss = new MaxSimpleString();
		String maxSameString = mss.getMaxSameString(str1, str2);
		System.out.println(maxSameString);
		
	}

	public String getMaxSameString(String str1, String str2) {
		//不加这个判断的话,如果str1或者str2有一个为null,下边会出现空指针的异常
		if (str1 != null && str2 != null) {
			// 先找出哪个串比较短
			String maxString = (str1.length() >= str2.length()) ? str1 : str2;
			String minString = (str1.length() < str2.length()) ? str1 : str2;

			// 需要两层for循环来实现
			/*
			 * 将短的那个串,进行长度依次递减的字串与较长的字串进行比较 外层循环控制的是:一共可以length-1进行多少次(第一次不进行-1,直接比较)
			 */
			for (int i = 0; i < minString.length(); i++) {
				for (int start = 0, end = minString.length() - i; end <= minString.length(); start++, end++) {
					// 因为length-1 可能是从左侧划掉一个char,也可能是从右侧。
					// 并且,minstring与循环的控制条件有关,所以不应该将对于短的字符串的修改保留在minstring上
					String subString = minString.substring(start, end);
					if (maxString.contains(subString)) {
						return subString;
					}
				}
			}
		}
		return null;
	}
}

拓展

对于两个字符串中的最大子串有多个的情况,可以参考下面这篇文章:
有多个最大相同子串的情况

I don’t want to let myself down!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值