【问题标题】:Non-repeating permutations of string in lexicographical order按字典顺序排列的字符串的非重复排列
【发布时间】:2014-06-19 02:23:37
【问题描述】:

当我看到this 时,我正在阅读有关字符串排列生成的信息。以下是帖子中提到的代码:

// Program to print all permutations of a string in sorted order.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Following function is needed for library function qsort(). Refer
   http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/ */
int compare (const void *a, const void * b)
{  return ( *(char *)a - *(char *)b ); }

// A utility function two swap two characters a and b
void swap (char* a, char* b)
{
    char t = *a;
    *a = *b;
    *b = t;
}

// This function finds the index of the smallest character
// which is greater than 'first' and is present in str[l..h]
int findCeil (char str[], char first, int l, int h)
{
    // initialize index of ceiling element
    int ceilIndex = l;

    // Now iterate through rest of the elements and find
    // the smallest character greater than 'first'
    for (int i = l+1; i <= h; i++)
      if (str[i] > first && str[i] < str[ceilIndex])
            ceilIndex = i;

    return ceilIndex;
}

// Print all permutations of str in sorted order
void sortedPermutations ( char str[] )
{
    // Get size of string
    int size = strlen(str);

    // Sort the string in increasing order
    qsort( str, size, sizeof( str[0] ), compare );

    // Print permutations one by one
    bool isFinished = false;
    while ( ! isFinished )
    {
        // print this permutation
        printf ("%s \n", str);

        // Find the rightmost character which is smaller than its next
        // character. Let us call it 'first char'
        int i;
        for ( i = size - 2; i >= 0; --i )
           if (str[i] < str[i+1])
              break;

        // If there is no such chracter, all are sorted in decreasing order,
        // means we just printed the last permutation and we are done.
        if ( i == -1 )
            isFinished = true;
        else
        {
            // Find the ceil of 'first char' in right of first character.
            // Ceil of a character is the smallest character greater than it
            int ceilIndex = findCeil( str, str[i], i + 1, size - 1 );

            // Swap first and second characters
            swap( &str[i], &str[ceilIndex] );

            // Sort the string on right of 'first char'
            qsort( str + i + 1, size - i - 1, sizeof(str[0]), compare );
        }
    }
}

// Driver program to test above function
int main()
{
    char str[] = "ABCD";
    sortedPermutations( str );
    return 0;
}

但此代码无法处理字符串具有重复字母(例如 abca)并因此生成重复排列的情况。

我们如何更改此算法以按字典顺序生成非重复排列。或者有其他方法可以吗?

【问题讨论】:

  • 你认为字符串abca的有效排列是什么?
  • 您是否尝试过重复运行此代码?
  • @500-InternalServerError...aabc,aacb,abac,abca,....等...共 12 个
  • 我认为可以有一个解决方案,而不是对字符串 once 进行排序,然后生成排列。
  • @DavidEisenstat...我没有...虽然我现在有并且它有效,现在看起来很合乎逻辑。如果按字典顺序打印字符串,则只能连续打印重复项,并且此算法可确保不会发生这种情况...无论如何谢谢...

标签: c string algorithm permutation


【解决方案1】:

David Eisenstat 在 cmets 中指出后,我运行程序,发现它没有打印重复项。我已经假设了这段代码会面临的某些问题,而实际上它不会。

我对代码为什么起作用的解释是:-

如果算法按字典顺序打印字符串,则只能连续打印重复项,如果您试运行此算法,您会看到它不会连续打印相同的字符串。如果重复的字符串没有在原始字符串之后打印,则不能在其他任何地方打印,以免字典错误被破坏

【讨论】:

    【解决方案2】:

    您的示例中没有重复的字母,只有输入字母中的字符。

    我不会为您提供现成的代码,而只是告诉您如何处理重复项。它很简单,可能不是最有效的,但还不错,它会使代码正常工作。

    您可以将其存储在可以处理重复项的容器中,而不是直接打印排列。

    IMO 字典树将有利于此目的。将大小为 N 的元素放入其中需要 O(N),因此它实际上不会恶化 Big-Oh 的时间复杂度(因为打印也需要 O(N),例如任何类型的 store 操作)。如果元素存在,您可以在那里计算欺骗或不做任何事情。

    然后你可以遍历树并打印不重复的条目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多