回溯法输出n对括号的合法组合

排列组合这种问题似乎用回溯法比较合适,括号只有左括号和或右扣号,把左扣号定好了,右括号也就定好了。

用一个栈来存中间结果,优先放左扣号,符合条件输出后回溯。

#include <stdio.h>
int main(int argc, char *argv[]) {
    int n = atoi(argv[1]);
    char s[10000];
    int si = -1;
    //未放入栈的左括号数
    int left_count = n;
    int i = 0;
    while (1) {
        if (left_count > 0) {
            //左括号还没放完,继续放
            s[++si] = ‘(‘;
            --left_count;
            continue;
        }
        //左括号已经放完了,可以输出了
        for (i = 0; i <= si; i++) {
            printf("%c", s[i]);
        }
        for (i = si + 1; i < n * 2; i++) {
            printf(")", s[i]);
        }
        printf("\n");
        //开始回溯, 直到能将某一个左扣号变成右扣号
        while (si >= 0) {
            if (s[si] == ‘(‘) {
                //s[0]到s[si-1]中,左括号数超过一半,才能将s[si]变成左扣号
                if ((n - left_count - 1) * 2 > si) {
                    s[si] = ‘)‘;
                    left_count++;
                    break;
                }
                left_count++;
            }
            si--;
        }
        if (si < 0) {
            //回溯不到了
            break;
        }
    }
}

输出结果:

[email protected]$ ./a.out 1
()
[email protected]$ ./a.out 2
(())
()()
[email protected]$ ./a.out 3
((()))
(()())
(())()
()(())
()()()

[email protected]$

./a.out 1
()

./a.out 2
(())
()()

./a.out 3
((()))
(()())
(())()
()(())
()()()

时间: 2024-11-05 12:17:47

回溯法输出n对括号的合法组合的相关文章

输出括号所有合法匹配

原文链接:http://blog.csdn.net/doc_sgl/article/details/8917476 简答题最后一题,编程实现所有括号的合法匹配 如输入3 输出:"((()))”, “(()())”, “(())()”, “()(())”, “()()()” 思路:深搜+剪枝,关键在于记录已经用掉的左括号个数和右括号的个数, 1,当用过的左括号个数小于右括号则非法: 2,当二者个数和大于2N则非法: 3,当二者个数相等且数目等于2N此时输出. #include <iostre

回溯法 -数据结构与算法

1.回溯法算法思想: 定义: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 1.回溯法适用:有许多问题,当需要找出它的解集(全部解)或者要求回答什么解是满足某些约束条件的最优解时,往往要使用回溯法. 2.有组织的穷举式搜索:回溯法的基本做法是搜索或者有的组织穷尽搜索.它能避免搜索所有的可能性.即避免不必要的搜索.这种方

算法思想之回溯法

一.概念 回溯:当把问题分成若干步骤并递归求解时,如果当期步骤没有合法选择,则函数将返回上一级递归调用,这种现象称为回溯. 回溯算法应用范围:只要把待求解问题分成不太多的步骤,每个步骤又只有不太多的选择,即可以考虑用回溯法. 回溯算法实际上是一个递归枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不

ACM:回溯法,八皇后问题,素数环

(一)八皇后问题 (1)回溯法 #include <iostream> #include <string> #define MAXN 100 using namespace std; int tot = 0, n = 8; int C[MAXN]; void search(int cur) { if(cur == n) ++tot; //递归边界,只要走到了这里,所有皇后必然不冲突 else for(int i = 0; i < n; ++i) { int ok = 1; C

南邮算法分析与设计实验3 回溯法

回溯法 实验目的: 学习编程实现深度优先搜索状态空间树求解实际问题的方法,着重体会求解第一个可行解和求解所有可行解之间的差别.加深理解回溯法通过搜索状态空间树.同时用约束函数剪去不含答案状态子树的算法思想,会用蒙特卡罗方法估计算法实际生成的状态空间树的结点数. 实验内容: 1.求24点问题 给定四个1-9之间的自然数,其中每个数字只能使用一次,用算术运算符+,-,*,/构造出一个表达式,将这4个正整数连接起来(可以使用括号),使最终的得数为24.要求根据问题的特征设计具体算法并编程实现,输入数据

javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题

赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支构成这两个结点之间的路径. ② 路径长度:结点路径上的分支数目称为路径长度. ③ 树的路径长度:从树根到每一个结点的路径长度之和. 以下图为例: A到F :结点路径 AEF : 路径长度(即边的数目) 2 : 树的路径长度:3*1+5*2+2*3=19: ④ 结点的带权路径长度:从该结点的到树的根结

回溯法总结

转  http://www.zhimengzhe.com/bianchengjiaocheng/Javabiancheng/257227.html 1.回溯法 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就"回溯"返回,尝试别的路径.回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为

【回溯法】八皇后问题(递归和非递归)

先贴代码,分递归回溯法和非递归回溯法 递归回溯法,代码如下: // test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <stdio.h> using namespace std; int a[9] = {0}; int n = 8; int count = 0; bool check

八皇后(回溯法)

题目内容 n*n的矩阵,作为棋盘,放置n个皇后,且它们都无法攻击其他皇后,求出放置方法 皇后的攻击方式,沿行.列.对角线都可以攻击其它皇后 基本思想 使用回溯法(穷举法) 所有的回溯问题都是由三个步骤组成:choose.explore.unchoose 因此对每个问题需要知道: choose what?   对于这个问题,我们选择每个字符串 how to explore?对于这个问题,我们对剩余的字符串做同样的事情. unchoose           做相反的操作选择 回溯法步骤 1.Def