`

搜索(三)——回溯

 
阅读更多

一、回溯 和 深度搜索 是什么关系
对于某一个搜索树来说(搜索树是起记录路径和状态判断的作用),回溯和DFS,其主要的区别是,回溯法在求解过程中不保留完整的树结构,而深度优先搜索则记下完整的搜索树。

 

二、递归回溯 和 迭代回溯

 

题目一:在n个数字中,任意找k个数字(k<=n),打印所有的可能的情况。

#include <iostream>
#include <vector>
using namespace std;

void output(vector<int>& s, int k){
     for(int j=1;j<=k;j++){
         cout<<s[j]<<" ";
     }
     cout<<endl;
}

//递归回溯
// 已经设置 s[1]~s[l-1],尝试设置 s[l] 
void recurse_traceback(vector<int>& s, int n, int k, int l){
    for(s[l]=s[l-1]+1;s[l]<n;s[l]++){
        if(l==k){
            output(s,k);
        }else{
            recurse_traceback(s,n,k,l+1);
        }
    }
}

//迭代回溯
// 模拟栈的使用 
void iterative_traceback(vector<int>& s, int n, int k, int l){
     s[l]=0;    //s[1]=0;
     while(l){
         while(s[l]<n){  //当前层s[l]已经设置,尝试做下一个动作
             if(l==k){   //到达最底层,打印结果 
                 output(s,k);
                 s[l]+=1;
             } else {    //否则深搜,进入下一层
                 l++;
                 s[l]=s[l-1]+1; 
             }
         }
         l--;    //下面处理完了,跳回上一层
         s[l]++; 
     }
}

int main(){
    int n=6;
    int k=3;
    vector<int> s(n+1,-1); //s=<-1,-1,-1,-1, -1,-1,-1>
    
    recurse_traceback(s,n,k,1);
    cout<<"-------------"<<endl;
    iterative_traceback(s,n,k,1);
    
    
	system("pause");
	return 0;
}        

 

 题目二:子串所有匹配位置
        写一个“非递归”的算法,找出pattern在长串中出现的位置,如输入长串是abcbc而pattern是abc时,要输出(0,1,2)、(0,3,4)、(0,1,4)

public class Test {
	private static void match(char[] pattern, char[] str) {
		int[] pos = new int[pattern.length]; // 默认为0???

		int l = 0;// 层次

		// 先设置第0层的首个值
		pos[l] = 0;

		while (l >= 0) {// 当前层至少在第0层;当第0层发生回溯时,退出

			// 当前层(当前层l已经设置值pos[l])
			while (pos[l] < str.length) {

				if (l == pattern.length - 1) {// 1. 当前到达叶节点
					if (check(pattern, str, pos) == true)// 仅在叶节点检查
						output(pos);

					pos[l]++;// 当前层设置为下一个值(不一定有效)

				} else { // 2. 当前未到叶节点

					l++;// 进入下一层

					pos[l] = pos[l - 1] + 1;// 设置下一层为它的首个可能值
				}
			}

			l--;// 回溯到上一层

			if (l >= 0)// 上一层取它的下一个可能值
				pos[l]++;
		}
	}

	private static boolean check(char[] pattern, char[] str, int[] pos) {
		boolean flag = true;

		for (int i = 0; i < pattern.length; i++) {
			if (pattern[i] != str[pos[i]]) {
				flag = false;
				break;
			}
		}

		return flag;
	}

	private static void output(int[] pos) {
		for (int i = 0; i < pos.length; i++) {
			System.out.print(pos[i] + "\t");
		}
		System.out.println();
	}

	public static void main(String[] args) {
		char[] p = { 'a', 'b', 'c' };
		char[] s = { 'a', 'b', 'c', 'b', 'c' };
		match(p, s);
	}

}

 

 

 

分享到:
评论

相关推荐

    迷宫——回溯,递归

    标题中的“迷宫——回溯,递归”指的是在编程问题解决中的一种经典算法,用于在二维矩阵或图中寻找路径。回溯法是一种试探性的解决问题的方法,它尝试通过不断扩展解决方案来找到答案,如果发现当前路径无法到达目标...

    算法分析论文——回溯算法的应用.zip

    回溯算法的时间复杂度通常与问题的规模和搜索空间的结构紧密相关。 回溯算法的核心思想可以概括为以下几点: 1. **深度优先搜索**:回溯算法通常采用深度优先策略来遍历问题的解空间树。这意味着先探索一条路径到尽...

    回溯法采用的搜索策略-五大常用算法——回溯算法详解及经典例题,算法数据结构

    回溯法是一种有效的解决问题的算法,它通过有组织的、系统化的搜索策略来寻找问题的解,特别适用于解决那些解的数量较大的问题。回溯法的核心思想是在搜索过程中,如果发现当前路径无法达到目标,就回溯到之前的状态...

    五大常见算法策略之——回溯策略 (1),算法数据结构

    在遇到无法满足条件的分支时,回溯算法会撤销最近的决策,尝试其他的可能性,这一过程就像在解空间树中进行深度优先搜索。在数据结构和算法领域,回溯策略是一种强大的工具,它可以用来解决如货郎问题、八皇后问题等...

    五大常用算法——回溯算法详解及经典例题,算法数据结构 五大常用算法

    回溯算法是一种常用的搜索算法,它可以用于解决许多复杂的问题。回溯算法的基本思想是,通过不断地尝试和回溯来找到问题的解。它可以看作蛮力法穷举搜索的改进,能够避免搜索所有可能的解,从而提高搜索效率。 在...

    五大常见算法策略之——回溯策略,算法数据结构

    回溯法是种选优搜索法,按选优条件向前搜索,以达到目标。下面通过几个例子来讨论这个算法策略。 货郎问题是一个经典的回溯策略应用例子。货郎问题有一个推销员,要到n个城市推销商品,他要找出一个包含所有n个城市...

    数据结构回溯法应用——背包问题

    在这个主题中,我们聚焦于一种经典的算法——回溯法,以及它在解决背包问题中的应用。回溯法是一种试探性的解决问题的方法,当遇到无法继续进行的情况时,会尝试撤销最近的选择,返回到一个更早的状态,寻找其他可能...

    N皇后求解问题——递归和回溯方法

    回溯是一种试探性的搜索策略,当尝试所有可能的解决方案都无法满足条件时,它会撤销之前的选择,然后尝试另一种可能性。在N皇后问题中,非递归实现通常使用栈来存储每一步的状态。基本步骤如下: 1. 创建一个空栈,...

    素数环 回溯法——C语言代码

    回溯法是一种在问题的解空间树中搜索问题解的方法,它尝试逐步构造可能的解,并在每一步检查当前选择是否可行。如果当前选择导致无法找到解,就撤销这个选择,尝试其他可能性,直到找到解决方案或者搜索完所有可能的...

    批处理作业调度问题 回溯法——C++代码

    回溯法通常用于解决约束满足问题(CSP)和搜索问题。在批处理作业调度问题中,每个作业代表一个任务,具有特定的执行时间和优先级。目标是找到一个最优的调度序列,使得所有作业都能在尽可能短的时间内完成,或者...

    回溯算法——n后问题

    在解决N后问题时,回溯算法通常采用深度优先搜索策略。从第一个位置开始,尝试放置皇后,然后检查是否与已放置的皇后冲突。如果有冲突,就将皇后移动到下一个位置继续尝试。如果所有位置都尝试过但仍然存在冲突,...

    算法设计——N后问题的回溯解法

    #### 三、代码分析与解释 1. **类定义**: - `Queen` 类包含了 N 后问题的解决方案。 - `Place` 函数:检查第 k 个皇后的位置是否与前面已经放置的皇后发生冲突(在同一行、列或对角线上)。 - `Backtrack` 函数...

    利用回溯法解决n皇后问题

    例如,当检查某一行的皇后位置时,可以利用已知的皇后位置信息,提前排除不可能的列,从而降低搜索空间。** **总的来说,利用回溯法解决n皇后问题,关键在于理解回溯算法的原理,正确地设计递归函数,以及有效地...

    回溯法求解子集和问题

    然而,它的缺点是效率较低,因为当问题的规模增大时,搜索空间会呈指数级增长。为了提高效率,可以考虑对输入数据进行预处理(如排序),或者使用剪枝技巧来减少不必要的计算。 总结来说,回溯法是解决子集和问题的...

    回溯与分支界限法——测试用例——互斥矩阵.rar

    回溯与分支界限法是两种在计算机科学中广泛使用的搜索策略,主要应用于解决优化问题和组合爆炸性问题。这两种方法都是在解决问题时通过系统地探索可能的解空间来找到最优解或满足特定条件的解。 回溯法是一种试探性...

    剑指offer计划28(搜索与回溯算法困难)---java(csdn)————程序.pdf

    【剑指Offer计划28:搜索与回溯算法困难】主要涵盖了两个经典的编程问题,一个是序列化二叉树,另一个是字符串的排列。这两个问题都涉及到深度优先搜索(DFS)和回溯算法。 1. **序列化二叉树**: - **题目描述**...

    剑指offer计划15( 搜索与回溯算法中等)---java(csdn)————程序.pdf

    总结以上三个知识点,我们可以看出在解决二叉树问题时,二叉搜索树的特性(有序性)被充分利用,而回溯法和深度优先搜索是解决复杂路径或状态问题的常用策略。这些技巧在实际编程中非常实用,可以帮助我们有效地处理...

    搜索专题——DFS

    当节点v的所在边都已被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复...

    剑指offer计划20( 搜索与回溯算法中等)---java(csdn)————程序.pdf

    【搜索与回溯算法】 搜索与回溯算法是计算机科学中用于解决一系列问题的重要方法,尤其是在处理具有约束条件的问题时。这些算法通常涉及到探索问题的所有可能解决方案,直到找到一个满足条件的解,或者证明所有可能...

Global site tag (gtag.js) - Google Analytics