排列组合

排列组合问题:

1. 字符串全排列(permutation)       转自:http://www.cnblogs.com/sujz/archive/2011/06/16/2082831.html

问题:给定字符串S,生成该字符串的全排列。
方法1:依次从字符串中取出一个字符作为最终排列的第一个字符,对剩余字符组成的字符串生成全排列,最终结果为取出的字符和剩余子串全排列的组合。
#include <iostream>
#include <string>
using namespace std;
 
void permute1(string prefix, string str)
{
    if(str.length() == 0)
        cout << prefix << endl;
    else
    {
        for(int i = 0; i < str.length(); i++)
            permute1(prefix+str[i], str.substr(0,i)+str.substr(i+1,str.length()));
    }
}
 
void permute1(string s)
{
    permute1("",s);
}
 
int main()
{
    //method1, unable to remove duplicate permutations.
    cout << "method1" << endl;
    permute1("ABA");
}
优点:该方法易于理解,但无法移除重复的排列,如:s="ABA",会生成两个“AAB”。

方法2:利用交换的思想,具体见实例,但该方法不如方法1容易理解。

排列组合_第1张图片

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;

void swap(char* x, char* y)
{
    char tmp;
    tmp = *x;
    *x = *y;
    *y = tmp;
}
 
/* Function to print permutations of string
   This function takes three parameters:
   1. String
   2. Starting index of the string
   3. Ending index of the string. */
void permute(char *a, int i, int n)
{
   int j;
   if (i == n)
     printf("%s\n", a);
   else
   {
        for (j = i; j <= n; j++)
       {
          if(a[i] == a[j] && j != i)  //为避免生成重复排列,当不同位置的字符相同时不再交换
           continue;
          swap((a+i), (a+j));
          permute(a, i+1, n);
          swap((a+i), (a+j)); //backtrack
       }
   }
} 
 
int main()
{
    //method2
    cout << "method2" << endl;
    char a[] = "ABA";
    permute(a,0,2);
    return 0;
}
两种方法的生成结果:
method1:
ABA
AAB
BAA
BAA
AAB

ABA

method2:

ABA
AAB
BAA

请按任意键继续. . .

2. 组合  转自:http://www.cnblogs.com/GoAhead/archive/2012/05/30/2526563.html

方法:依次递归地对所有的组合形式进行枚举,从一个字符到n个字符。

对于m个字符的组合,遍历n个字符,决定是否取当前的字符,一直取到足够m个为止,即遍历所有的取法。

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

// 函数功能 : 从一个字符串中选m个元素
// 函数参数 : pStr为字符串, m为选的元素个数, result为选中的
// 返回值 :   无
void Combination_m(char *pStr, int m, vector<char> &result)
{
    if(pStr == NULL || (*pStr == '\0'&& m != 0))
        return;

    if(m == 0) // 递归终止条件
    {
        for(unsigned i = 0; i < result.size(); i++)
            cout << result[i];
        cout << endl;
        return;
    }
    // 选择这个元素
    result.push_back(*pStr);
    Combination_m(pStr + 1, m - 1, result);
    result.pop_back();
    // 不选择这个元素
    Combination_m(pStr + 1, m, result);
}
// 函数功能 : 求一个字符串的组合
// 函数参数 : pStr为字符串
// 返回值 :   无
void Combination(char *pStr)
{
    if(pStr == NULL || *pStr == '\0')
        return;

    int number = strlen(pStr);
    for( int i = 1; i <= number; i++)
    {
        vector<char> result;
        Combination_m(pStr, i, result);
    }
}

int main()
{
    char str[] = {'A', 'B', 'A', '\0'};
    Combination(str);
    return 0;
}

结果:

A
B
A
AB
AA
BA
ABA

问题:由于是组合,因此字符串中不能存在相同的字符,如若存在,则需要将他们当做不同的值对待,即不同位置上的相同字符认为是不同的字符。

注: 想要去除重复组合,在进行之前就应该将字符串中的重复字符筛选掉。

你可能感兴趣的:(排列组合)