打印所有重复数字排列的算法

标签 algorithm

我已经成功地设计了算法来打印所有重复数字的排列。但是我设计的算法有一个缺陷。仅当字符串的字符是唯一的时它才有效。

有人可以帮助我扩展算法以应对字符串的字符可能不唯一的情况吗.. 到目前为止我的代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<iostream>

using namespace std;

void _perm(char *arr, char*result, int index)
{
    static int count = 1;
    if (index == strlen(arr))
    {
        cout << count++ << ". " << result << endl;
        return;
    }
    for (int i = 0; i < strlen(arr); i++)
    {
        result[index] = arr[i];
        _perm(arr, result, index + 1);
    }
}

int compare(const void *a, const void *b)
{
    return (*(char*)a - *(char*)b);
}



void perm(char *arr)
{
    int n = strlen(arr);
    if (n == 0)
        return;
    qsort(arr, n, sizeof(char), compare);
    char *data = new char[n];
    _perm(arr, data, 0);
    free(data);
    return;
}



int main()
{
    char arr[] = "BACD";
    perm(arr);
    return 0;
}

我正在按字典顺序打印输出字符串。

我指的是本页中的示例 3。

http://www.vitutor.com/statistics/combinatorics/permutations_repetition.html

谢谢。

最佳答案

您的代码不会打印排列,但会重复从字符串池中抽取四次。它将产生4^4 == 256组合,其中之一是“AAAA”。

链接到的代码 Karnuakar 将为您提供字符串的排列,但不会区分某些字母的多次出现。您需要一些方法来防止在每个递归步骤中使用相同的字母进行递归。在 C++ 中,这可以通过集合来完成。

下面的示例代码使用典型的 C 字符串,但使用终止符 '\0'检测结束。来自 <cstring> 的 C 字符串函数不需要。除非对原始字符串进行排序,否则不会对输出进行排序。

#include <iostream>
#include <algorithm>
#include <set>

using namespace std;

void perm(char *str, int index = 0)
{
    std::set<char> used;

    char *p = str + index;
    char *q = p;

    if (*p == '\0') {
        std::cout << str << std::endl;
        return;
    }

    while (*q) {
        if (used.find(*q) == used.end()) {
            std::swap(*p, *q);
            perm(str, index + 1);
            std::swap(*p, *q);

            used.insert(*q);
        }
        q++;
    }
}

int main()
{
    char arr[] = "AAABB";
    perm(arr);

    return 0;
}

这将产生 5! == 120 “ABCDE”的排列,但只有 5! / (2! 3!) == 10 “AAABB”的独特排列。它还将从链接的练习中创建 1260 个排列。

关于打印所有重复数字排列的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26714448/

相关文章:

algorithm - 如何检查循环单链表是否为回文?

string - 从大量字符串中搜索 "is in string"的高效数据结构

c++ - 计算三次贝塞尔曲线的最快方法?

javascript - 如何在多列上对数组进行排序?

生成均匀分布的随机排列的算法

java - 如何进一步优化这个色差函数?

c++ - A-Star 搜索算法找不到有效路径

algorithm - 匹配二进制模式包括 "don' t cares"

algorithm - 查找两个字符串的相似程度

algorithm - 为什么 BIDEN 使用半最大周期进行搜索空间修剪?