zoukankan      html  css  js  c++  java
  • 面试题之括号匹配分析( 出栈序列是否合法,给定一个入栈序列,求所有可能的出栈序列等等)

    题目:括号匹配分析

    给定字符串,输出括号是否匹配,例如,

    1. "()" yes;

    2. ")(" no;

    3. "(abcd(e)" no;

    4. "(a)(b)" yes。

    要求必须用递归写,整个实现不可以出现一个循环语句。

    分析

    这个题目很多同学都见过了,如果没有后面的条件,会张口就说就来用栈来实现,时间复杂度O(n),空间复杂度O(n)。这个是很好的一个解答,没有 问题的。但是我们在做面试题,准备面试的过程中,每一个题目都不应该仅仅局限于某一个方法。应该尝试更多的思路,尽管有些思路的时间、空间复杂度并不是很 好,但是可以带来变化,举一反三,这才是真正的收获。

    这个题要求了,只目能使用递归并且不能出现循环语句。这个时候,我们应该如何处理呢?其实告诉了大家递归,就比较好想了:怎么定义好问题和子问题。

    如果字符串中的括号是匹配的,则'('的数量和')'的数量是相等的,反之是不相等的。这样,在递归的过程中,可以保存一个变量,用来记录'('的 数量和')'的数量是否匹配。这样定义递归问题f(p,count),表示当前字符p之前的字符串中'('的数量和')'的数量的匹配情况,p表示指向当 前字符的指针。初始的时候,f(p, 0),递归的过程如下:

    1. 如果p为空,则考察count是否为0,如果为0,则匹配;如果不为0,则不匹配;

    2. 如果不为空,则考察当前字符p,如果p='(',则递归调用f(p++, count++);如果p=')',则递归调用f(p++, count--)。如果p是其他的字符,并不是'('和')',则递归调用f(p++, count),count不变,继续考虑下一次字符。其中需要检查和保证count>=0.

    其实,递归的问题有的时候不是那么好像的,需要大家不断的练习。如果不采用count来记录括号匹配的情况,这个题目的递归也不好想。

    基于栈的代码:

    bool isMatched(const char *str)
    {
        stack<char> s;
        while(*str)
        {
            if(*str=='(')
            {
                s.push('(');
            }
            else if(*str==')')
            {
                if(!s.empty())//这里很重要,保证了如果输入)(,就直接退出
                {
                    s.pop();
    
                }
                else
                {
                    return false;
                }
            }
            str++;
        }
        return s.empty();
    }

    递归的代码:下面是我刚开始写的,有什么错误吗?

    bool isMatchedRec(char *p,int count)
    {
        if(*p=='')
        {
            return count==0;//如果p为空,则考察count是否为0,如果为0,则匹配;如果不为0,则不匹配;
        }
        else
        {
            if(*p=='(')
            {
                //return isMatchedRec(p++,count++); 错误,在递归内要写前缀++,不要写后缀,否则无穷递归。
                 
                return isMatchedRec(++p,++count);
            }
            else if(*p==')')
            {
                return isMatchedRec(++p,--count);
            }
            else
            {
                return isMatchedRec(++p,count);
            }
        }
    }

    错误在哪里;

    假设我们输入“)(”,返回的还是true。

    原因是没有没有检查count>=0.

    正确的代码:

    bool isMatchedRec(char *p,int count)
    {
        if(*p=='')
        {
            return count==0;//如果p为空,则考察count是否为0,如果为0,则匹配;如果不为0,则不匹配;
        }
        else
        {
            if(count>=0)
            {
                if(*p=='(')
                {
                     
                 
                    return isMatchedRec(++p,++count);
                }
                else if(*p==')')
                {
                    return isMatchedRec(++p,--count);
                }
                else
                {
                    return isMatchedRec(++p,count);
                }
            }
            else 
                return false;
           
        }
    }

    可以把上面代码再简化下:

    bool isMatchedRec2(const char* s,int count)
    {
        if(count<0)
            return false;
    
        if(*s=='')
        {
            return count==0;
        }
        else
        {
            if(*s=='(')
                count++;
            else if(*s==')')
                count--;
        }
    
        return isMatchedRec2(++s,count);
    }

    参考:http://blog.csdn.net/buaa_shang/article/details/11726619

    扩展问题;

    假设字符串中包含{,[,( 三种括号,请判断是否匹配。

    http://blog.chinaunix.net/uid-28458801-id-3664897.html

    bool isPair(char a,char b)
    {
        bool flag=true;
        if(a=='{' && b=='}')
            flag=true;
        else if(a=='[' && b==']')
            flag=true;
        else if(a=='(' && b==')')
            flag=true;
        else
            flag=false;
    
        return flag;
    }
    
    bool isMatched(const char *str)
    {
        stack<char> s;
        while(*str)
        {
            if(*str=='{' || *str=='[' || *str=='(' )
            {
                /*if( (s.top()=='{') || (s.top()=='['&&*str!='{') && (s.top()=='('&& *str=='(') )
                    s.push(*str);
                else
                    return false;
                    */
                s.push(*str);
    
            }
            else if(*str=='}' || *str==']' || *str==')' )
            {
                if(!s.empty())//这里很重要,保证了如果输入)(,就直接退出
                {
                    if(isPair(s.top(),*str))
                    {
                        s.pop();
                    }
                    else
                    {
                        return false;
                    }
    
    
                }
                else
                {
                    return false;
                }
            }
            str++;
        }
        return s.empty();
    }
     

    题目扩展

            给你一个字符串,里面只包含"(",")","[","]","{","}"几种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
            例如:
            []是匹配的,所需括号个数为 0;([])[]是匹配的, 所需括号个数为 0;((]是不匹配的, 所需最少括号个数为 3;([)]是不匹配的,所需最少括号个数为 2.

     

            这道变种题大多数人的解题思路都是动态规划,思路如下。不知道大家有没有好的别的方法,求教。

         1)用 dp[i][j] 表示从位置 i  到字符位置 j 所需的最少括号数。假定字符串是 “[ ( )”, 那么 dp[0][0] = dp[1][1]  = dp[2][2] = 1。

         

        2)如果我们要算dp[i][j+1], 那么,最坏的情况是使得没有被匹配的括号数增加了,即 dp[i][j+1] 最多为 min( dp[i][j] + 1, dp[i+1][j+1] + 1). 但是,这可能不是我们想要的答案,因为在刚才的例子里,即:假定字符串是 “[ ( )”, 那么 dp[0][1] = dp[0][0] + 1= 2, 但是 dp[1][2] 却不等于 dp[1][1] + 1.

        

        3)那么,什么情况下dp[i][j+1] = dp[i][j] + 1?只有当 字符串里从i 到 j 没有任何字符与第 j + 1 个字符匹配的时候。但是,如果存在和第 j + 1 个字符匹配的情况,问题就不一样了。

     

        4)假设在i 到 j 之间存在一个字符(比如在位置 k)与第 j + 1 个字符匹配,那么我们相当于把原来的字符串分成了两个部分dp[i][k-1] 和 dp[k+1][j], 因为第k 个 和 j + 1 个字符已经匹配掉了。而且,我们不会再考虑 i 到 k - 1 的字符会和 k + 1 到 j 之间的字符匹配的情况,因为我们已经把这两个部分完全分开了。话句话说 dp[i][j+1] = min(min( dp[i][j] + 1, dp[i+1][j+1] + 1),  dp[i][k-1] + dp[k+1][j]).

    #include<iostream>
    #include<string>
    #include<memory.h>
    using namespace std;
    bool is(char a, char b){
        if(a == '(' && b == ')')
            return 1;
        if(a == '[' && b == ']')
            return 1;
        if(a == '{' && b == '}')
            return 1;
        return 0;
    }
    int main(){
        //dp[i][j] 表示从第i位至第j位的最小匹配长度
        int t, i, j, k, dp[105][105];
        cin >> t;
        while(t--){
            string s;
            cin >> s;
            memset(dp, 0, sizeof(dp));
            for(i = 0; i <= s.length(); ++i){
                dp[i][i] = 1;
            }
            for(i = 2; i <= s.length(); ++i){
                for(j = i - 1; j >= 1; --j){
                    dp[j][i] = dp[j][i - 1] + 1;
                    for(k = j; k < i; ++k){
                        if(is(s[k - 1], s[i - 1])){
                            dp[j][i] = min(dp[j][i], dp[j][k - 1] + dp[k + 1][i - 1]);
                        }
                    }
                }
            }
            cout << dp[1][s.length()] << endl;
        }
        return 0;
    }

     改写的更容易看懂 的代码:

    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j])k [i,j)

    bool isPair(char a,char b)
    {
         if(a == '(' && b == ')')
            return 1;
        if(a == '[' && b == ']')
            return 1;
        if(a == '{' && b == '}')
            return 1;
        return 0;
    }
    
    int match(int dp[100][100],char s[])
    { 
        for(int i=0;i<100;i++)
            for(int j=0;j<100;j++)
                dp[i][j]=0;
    
        int len=strlen(s);
        for(int i=0;i<=len;i++)
            dp[i][i]=1;
    
        for(int j=2;j<=len;j++)
        {
            for(int i=j-1;i>=1;i--) //i从1开始,说明dp[0]不存
            {
                dp[i][j]=dp[i][j-1]+1;
                for(int k=i;k<j;k++)
                {
                    if(isPair(s[k-1],s[j-1]))
                    {
                        dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j-1]);
                    }
                }
             
            }
        }
        return dp[1][len];
    }

     递归版:

     //递归版
    #include<stdio.h>
    #include<string.h>
    
    const int inf = 0x0fffffff;
    #define min(x, y)(x < y ? x : y)
    #define low(x, y)((x == '(' && y == ')') || (x == '[' && y == ']'))
    char str[110];
    int dp[110][110];
    int fun(int x,int y)
    {
        if(dp[x][y] != -1)
            return dp[x][y];
        if(x > y)return 0;
        if(x == y)return 1;
        int ans = inf;
        if(low(str[x], str[y]))
            ans = min(ans, fun(x + 1, y - 1));
        for(int i = x;i < y; ++ i)
            ans = min(ans, fun(x, i) + fun(i + 1, y));
        dp[x][y] = ans;
        return ans;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T --)
        {
            scanf("%s", str);
            int len = strlen(str);
            memset(dp, -1, sizeof(dp));
            printf("%d
    ", fun(0, len - 1));
        }
    }

    参考:http://blog.acmj1991.com/?p=1142

    http://www.dewen.org/q/8653/%E4%B8%80%E4%B8%AA%E6%8B%AC%E5%8F%B7%E5%8C%B9%E9%85%8D%E7%9A%84%E6%89%A9%E5%B1%95%E9%97%AE%E9%A2%98

    另一题:

    输入括号的数目,输出括号的各种合法匹配样式

    输入 2

    输出 

     (())

    ()()

    据说这是一道某公司的面试题,我们先来分析一下。括号匹配有合法有的不合法 如 (()))( 这样就不是合法的匹配样式。为了避免这种情况的出现,记录当前左括号的个数和右括号的个数,使右括号的个数不大于左括号的个数。主要思想类似于0-1背包问题,当进行到某一步的时候 有两种方法:放'(' 和 放 ')'

    void matching(int left,int right,int sum,vector<char> bracket)
    {
        if (left==sum&&right==sum)  //如果左边和右边都为要匹配的个数,则输出结果
        {
            vector<char>::iterator iter=bracket.begin();
            for ( ;iter!=bracket.end();iter++)  
            {
                cout<<*iter<<' ';
            }
            cout<<endl;
            return ;
        }
        if (left<=sum)
        {
            bracket.push_back('(');    //放入左括号,然后递归
            matching(left+1,right,sum,bracket);
            bracket.pop_back();        //递归后弹出左括号
        }
        
        if (left>right&&left<=sum)
        {
            bracket.push_back(')');
            matching(left,right+1,sum,bracket);
            bracket.pop_back();
        }
    }
    int main(int argc, char* argv[])
    {
        vector<char> bracket;    //记录当前的匹配样式
        int num;
        cin>>num;                //输入括号的个数 
        matching(0,0,num,bracket);
        return 0;
    }

    我最开始想的是回溯法,应该和八皇后问题思路一致。但这个程序不是。上面递归程序不好理解。

    可以举个例子:sum=3时,

    最开始一值是运行第二个递归:

    (((,

    接着:

    放入一个),接着递归,又放入一个),又放入); 最后变成了:

    ((()));

     输出这个之后。

     给定一个入栈序列,求所有可能的出栈序列

    有2n个人排成一队进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票可找零,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)。

    对于这个例子,剧院要想总有零钱可找,那么目前进入剧院的人数中,揣着10元钞票的人数必须少于等于揣着5元钞票的,不然肯定在某个人那出现没零钱找的情况。

    现在回到正题上来对于一个给定入栈序列,怎么求它的出栈序列呢?

    我们可以把入栈记为1,出栈记为0.那么前缀子序列中1的个数必须大于等于0的个数,即入栈次数要大于等于出栈次数,如1 1 0 1 0 0,它的任意前缀序列中1的个数是大于等于0的个数的。

    我们来看个例子:对于1 2 3这个入栈序列,1 1 0 1 0 0就是一个入栈出栈序列,第一个1代表元素1入栈,然后第二个1代表元素2入栈,然后第三个是0,代表出栈,即元素2出栈,然后第四个是1,代表元素3入栈,然后第五个是0,代表出栈,即元素3出栈,然后第六个是0,代表元素1出栈。最后1 1 0 1 0 0就代表了出栈序列2 3 1。

    那么现在的问题就转换为如何求出所有符合条件的0 1序列了。其实这和以下问题相同:给定括号对数,输出所有符合要求的序列。如2对括号,输出有()()或者(())两种。1可以看成'(',0可以看成‘)’。

    下面贴上本人的程序,并给出详细注释。

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


    void func(vector<char>kind,int count[],int n)
    {
        if(count[0]>=1)
        {
            kind.push_back('(');
            count[0]--;
            func(kind,count,n);
            count[0]++;
            kind.pop_back();
        }
        if((count[1]>=1) && (count[1]>count[0]))
        {
            kind.push_back(')');
            count[1]--;
            func(kind,count,n);
            count[1]++;
            kind.pop_back();
        }
        if(kind.size()==2*n)
        {
            vector<char>::iterator iter;
            for(iter=kind.begin();iter!=kind.end();iter++)
            {
                cout<<(*iter)<<" ";
            }
            cout<<endl;
        }
    }


    int main()
    {
        int n;
        cout << "please input the number of ():" << endl;
        cin>>n;
        int count[2]={n-1,n};
        vector<char>kind;
        kind.push_back('(');
        func(kind,count,n);
        return 0;
    }

    count[0]存着左括号数目,count[1]存着右括号数目。一开始kind中压入左括号,因为第一个肯定是左括号。然后count数组初始化为n-1个左括号,n个右括号。然后我们递归的处理。如果剩余左括号数count[0]大于0,就可以把左括号压栈。而对于右括号,栈中左括号个数必须多于右括号个数,也就是剩余右括号个数大于左括号个数,即count[1]>count[0]时,才能将右括号压栈。如果栈中元素个数达到2n时,就把栈中元素输出。

    下面贴出出栈序列代码,几乎和上面相同。

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


    int number=0;
    void func(vector<int>kind,int count[],int n,int A[])
    {
        if(count[0]>=1)
        {
            kind.push_back(1);
            count[0]--;
            func(kind,count,n,A);
            count[0]++;
            kind.pop_back();
        }
        if((count[1]>=1) && (count[1]>count[0]))
        {
            kind.push_back(0);
            count[1]--;
            func(kind,count,n,A);
            count[1]++;
            kind.pop_back();
        }
        if(kind.size()==2*n)
        {
            vector<int>::iterator iter;
            stack<int>stk;
            int j=0;
            for(iter=kind.begin();iter!=kind.end();iter++)
            {
                //cout<<(*iter)<<" ";
                if(1==(*iter))
                {
                    stk.push(A[j]);
                    j++;
                }
                else
                {
                    cout<<stk.top()<<" ";
                    stk.pop();
                }
            }
            number++;
            cout<<endl;
        }
    }


    int main()
    {
        int n,i;
        cout << "please input the number:" << endl;
        cin>>n;
        int A[n];
        cout << "please input the push sequence:" << endl;
        for(i=0;i<n;i++)
        {
            cin>>A[i];
        }
        int count[2]={n-1,n};
        vector<int>kind;
        kind.push_back(1);

        cout<<"the result is:"<<endl;
        func(kind,count,n,A);
        cout<<"total:"<<number<<endl;
        return 0;
    }

    参考:http://blog.csdn.net/zz198808/article/details/7585385

    一篇文章:

    #include<iostream>
    #include<stack>
    using namespace std;
    
    static int counter;
    
    void outprint(stack<int> q){
        while (q.size() != 0)  {
            cout << q.top() << "-> ";
            q.pop();
        }
        cout << endl;
        counter++;
        return;
    }
    
    //q 存放入栈序列
    //stk 用于模拟入栈过程
    //output 用于存放可能的出栈序列
    void allPopSeq(stack<int> q,stack<int> stk,stack<int> output){
        if((q.size() == 0)&&(stk.size()==0)&&(output.size() == 5)) {
            outprint(output);
            return;
        }
        if(q.size()!=0){//入栈
            int v = q.top();   
            stk.push(v);   
            q.pop();
            allPopSeq(q,stk,output);
            stk.pop();
            q.push(v);//回溯恢复
        }
        if(stk.size()!=0) //出栈
        {
            int v = stk.top();
            stk.pop();
            output.push(v);
            allPopSeq(q,stk,output);
            output.pop();
            stk.push(v);//回溯恢复
        }
        return;
    }
    int main()
    {
        int arr[5] = { 1, 2, 3, 4, 5 };
        stack<int> stkValues;
        stack<int> stkOutput;
        stack<int> tmp;
        int i;
        for (i = 0; i != 5; ++i){
            stkValues.push(arr[i]);
        }
        allPopSeq(stkValues, tmp, stkOutput);
        cout << counter << endl;
    }
     

    http://www.cnblogs.com/fxplove/articles/2500898.html

    程序员面试题精选100题(24)-栈的push、pop序列[数据结构]  

    题目:输入两个整数序列。其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序。为了简单起见,我们假设push序列的任意两个整数都是不相等的。

    比如输入的push序列是1、2、3、4、5,那么4、5、3、2、1就有可能是一个pop系列。因为可以有如下的push和pop序列:push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop,这样得到的pop序列就是4、5、3、2、1。但序列4、3、5、1、2就不可能是push序列1、2、3、4、5的pop序列。

    分析:这到题除了考查对栈这一基本数据结构的理解,还能考查我们的分析能力。

    这道题的一个很直观的想法就是建立一个辅助栈,每次push的时候就把一个整数push进入这个辅助栈,同样需要pop的时候就把该栈的栈顶整数pop出来。

    我们以前面的序列4、5、3、2、1为例。第一个希望被pop出来的数字是4,因此4需要先push到栈里面。由于push的顺序已经由push序列确定了,也就是在把4 push进栈之前,数字1,2,3都需要push到栈里面。此时栈里的包含4个数字,分别是1,2,3,4,其中4位于栈顶。把4 pop出栈后,剩下三个数字1,2,3。接下来希望被pop的是5,由于仍然不是栈顶数字,我们接着在push序列中4以后的数字中寻找。找到数字5后再一次push进栈,这个时候5就是位于栈顶,可以被pop出来。接下来希望被pop的三个数字是3,2,1。每次操作前都位于栈顶,直接pop即可。

    再来看序列4、3、5、1、2。pop数字4的情况和前面一样。把4 pop出来之后,3位于栈顶,直接pop。接下来希望pop的数字是5,由于5不是栈顶数字,我们到push序列中没有被push进栈的数字中去搜索该数字,幸运的时候能够找到5,于是把5 push进入栈。此时pop 5之后,栈内包含两个数字1、2,其中2位于栈顶。这个时候希望pop的数字是1,由于不是栈顶数字,我们需要到push序列中还没有被push进栈的数字中去搜索该数字。但此时push序列中所有数字都已被push进入栈,因此该序列不可能是一个pop序列。

    也就是说,如果我们希望pop的数字正好是栈顶数字,直接pop出栈即可;如果希望pop的数字目前不在栈顶,我们就到push序列中还没有被push到栈里的数字中去搜索这个数字,并把在它之前的所有数字都push进栈。如果所有的数字都被push进栈仍然没有找到这个数字,表明该序列不可能是一个pop序列。

    基于前面的分析,我们可以写出如下的参考代码:

    #include <stack>
    
    /////////////////////////////////////////////////////////////////////////////
    // Given a push order of a stack, determine whether an array is possible to 
    // be its corresponding pop order
    // Input: pPush   - an array of integers, the push order
    //        pPop    - an array of integers, the pop order
    //        nLength - the length of pPush and pPop
    // Output: If pPop is possible to be the pop order of pPush, return true.
    //         Otherwise return false
    /////////////////////////////////////////////////////////////////////////////
    bool IsPossiblePopOrder(const int* pPush, const int* pPop, int nLength)
    {
          bool bPossible = false;
    
          if(pPush && pPop && nLength > 0)
          {
                const int *pNextPush = pPush;
                const int *pNextPop = pPop;
    
                // ancillary stack
                std::stack<int> stackData;
    
                // check every integers in pPop
                while(pNextPop - pPop < nLength)
                {
                      // while the top of the ancillary stack is not the integer 
                      // to be poped, try to push some integers into the stack
                      while(stackData.empty() || stackData.top() != *pNextPop)
                      {
                            // pNextPush == NULL means all integers have been 
                            // pushed into the stack, can't push any longer
                            if(!pNextPush)
                                  break;
    
                            stackData.push(*pNextPush);
    
                            // if there are integers left in pPush, move 
                            // pNextPush forward, otherwise set it to be NULL
                            if(pNextPush - pPush < nLength - 1)
                                  pNextPush ++;
                            else
                                  pNextPush = NULL;
                      }
    
                      // After pushing, the top of stack is still not same as 
                      // pPextPop, pPextPop is not in a pop sequence
                      // corresponding to pPush
                      if(stackData.top() != *pNextPop)
                            break;
    
                      // Check the next integer in pPop
                      stackData.pop();
                      pNextPop ++;
                }
    
                // if all integers in pPop have been check successfully, 
                // pPop is a pop sequence corresponding to pPush 
                if(stackData.empty() && pNextPop - pPop == nLength)
                      bPossible = true;
          }
    
          return bPossible;
    }

    http://zhedahht.blog.163.com/blog/static/25411174200732102055385/

     或者判断出栈序列是否合法

    输入两个整形序列,*put,*out,分别表示入栈和出栈,判断出栈是否符和入栈要求。

    假设入栈为 首先1,2,3,4,5.出栈顺序为4,3,5,1,2
    分析:要得到4,则需将1,2,3,4全部入栈,然后pop得到4,输出3,因为栈顶元素即为3,直接输出即可。如果要得到5,需要将入栈队列中的5压入栈,然后输出。此时入栈队列已经为空。栈顶元素为2,底为1.此时需要输出1,但是要先输出2,错误,则此出栈顺序不合理。
     
    即如果元素在栈顶,直接pop得到,若不在栈顶,需要从入栈队列找到她,一直入栈,然后在pop。否则无法顺利。
     
    代码: 这个代码写的还可以
     bool Judge(int *put,int *out,int len)
    {
       bool val=false;
       if(put&&out&&len>0)
       {
         int *p=put;
         int *q=out;
         stack<int> a;
        while(q-out<len)
       {  
            while(a.empty()||*q!=a.top())    //如果栈为空或者栈顶元素不等于*q  则需寻找
            {
              if(!p)
               break;
              a.push(*p);
              if(p-put<len)   //判断入栈队列是否含有元素
                 p++;
              else
                 p=NULL;
     
              }
              if(*q!=a.top())  //全部入栈后还是不等
                  break;
              a.pop();
              q++;    //判断下一个
        }
         if(a.empty()&&(q-out==len))
                 val=true;
       }
      return     val;
    }
     
     
    扩展,给出一组数字为出栈队列,求其可能的入栈队列。
     
    分析:可以根据这组数字,全排列出所有组合,然后每一个组合利用上面的函数判别即可,如果true 即输出。
     
    代码:
        void fun(int *a,int *begin,int n,int *b)    //全排列求解
        {
         if(begin-a==n)
         {
            if(Judge(a,b,n)
                 for(int i=0;i<n;i++)
                  cout<<a[i]<<"  满足条件!!"<<endl;
         }
        else
        {
           for(int *temp=beign;temp-a<n;temp++)
               {
                int val=*begin;
                    *begin=*temp;
                    *temp=val;
                    fun(a,begin+1,n,b);
                     *temp=*begin;
                    *begin=val;
                 }
         }
          
     }
     
    void Show(int *b,int n)
    {
      int *a=new int[n];
      for(int i=0;i<n;i++)
           a[i]=n[i];
        fun(a,a,n,b);
       delete []a;
    }
     
     
    int main()
    {
        int b[]={4,5,3,2,1};
        Show(b,5);
    }

     参考:

    http://blog.163.com/m13591120447_1/blog/static/21637918920132270746190/

    http://blog.sina.com.cn/s/blog_4ac9f56e01014vcs.html

     http://blog.chinaunix.net/uid-21712186-id-1818123.html

  • 相关阅读:
    难以表述的话
    王爽《汇编第二版》实验9
    Delphi 文件操作资料
    根据条件改变cxGrid行与列颜色
    汇编笔记总结 之 跳转
    汇编笔记之三 第一个程序
    汇编笔记之四 包含多个段的程序
    汇编中的数据类型
    FastReport 参数的使用
    Winform:SaveFileDialog使用(数据导出示例)
  • 原文地址:https://www.cnblogs.com/youxin/p/3351944.html
Copyright © 2011-2022 走看看