深度优先搜索之困难的串

1. 问题描述:

如果一个字符串包含两个相邻的重复子串,则称它为容易的串,其他串称为困难的串
如:BB,ABCDACABCAB,ABCDABCD都是容易的,A, AB, ABA, D, DC, ABDAB, CBABCBA都是困难的。
输入正整数n, L 输出由前L个字符(大写英文字母)组成的,字典序第n小的困难的串。
例如,当L=3时,前7个困难的串分别为:
A, AB, ABA, ABAC, ABACA, ABACAB, ABACABA
n指定为4的话,输出ABAC

2. 因为是要进行试探的结果那么我们这里使用dfs来进行解决,其中这道题目涉及到两个难点,一是维持字典序的问题,另外一个是如何判断是否为困难的串的问题

① 维持字典序的话我们能够尽量往深的地方搜索,就尽量往深的地方搜索,而尽量不去搜索它的横的地方,即能不搜索它的兄弟尽量不搜索它的兄弟

所以这里当把当前的字符加进来的时候,就永远不会退回去去搜索它的平行状态即不搜索它的兄弟元素了,就没有了平行状态了,所以此时就不需要进行回溯了,因为它不受到平行状态的影响了

② 二是要解决如何判断是否为困难的串的问题,这里使用到了一种技巧就是不用去搜索它的所有的情况,即不用相邻一个一个进行判断,相邻两个两个字符进行判断...我们考虑到这里传进方法来的本来就是一个困难的串,所以并不需要像上面这样进行搜索情况的判断,只需要考虑当前加入的字符与其他字符组合起来再与相邻长度的字符串进行比较来看一下是否相同,如果相同那么加进来这个字符之后变成了容易的串,那么这个字符应该舍弃

3. 具体的代码如下:

import java.util.Scanner;
public class Main{
	static int n;
	static int count;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		int L = sc.nextInt();
		dfs("", L);
		sc.close();
	}
	
	private static void dfs(String s, int L) {
		for(char c = 'A'; c < 'A' + L; c++){
			if(isHard(s, c)){
				String prefix = s + c; 
				System.out.println(prefix);
				count++;
				if(count == n){
					System.exit(0);
				}
				dfs(prefix, L);
			}	
		}
	}

	private static boolean isHard(String prefix, char c){
		int count = 0;
		for(int i = prefix.length() - 1; i >= 0; i -= 2){
			String s1 = prefix.substring(i, i + count + 1);
		    String s2 = prefix.substring(i + count + 1) + c;
		    if(s1.equals(s2)) return false;
		    count++;
		}
		      return true;
	}
}

 判断是否为困难的串有是有传入的并不知道是什么样子的串,那么就需要对它所有的情况进行搜索

4. 下面是具体判断是否是困难的串的方法:

判断的代码如下:(调试的时候在截取完字符串之后使用输出语句查看输出的内容来判断代码判断是否正确

import java.util.Scanner;
public class Main{
	static int n;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s = sc.nextLine();
		n = s.length();
		isHard(s);
		sc.close();
	}

	private static void isHard(String s){
		boolean flag = true;
		for(int index = 1; index <= n / 2; index++){
			for(int j = n; j - 2 * index >= 0; j -= index){
				String prefix2 = s.substring(j - index, j);
				String prefix1 = s.substring(j - 2 * index, j - index);
				//System.out.println(prefix1 + " " + prefix2);
				if(prefix1.equals(prefix2)){
					System.out.println("不是一个困难的串");
					flag = false;
					break;
				}
			}
				if(flag == false){
					break;
				}
		}
				if(flag){
					System.out.println("是一个困难的串");
				}
	}	
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值