Are there any better methods to do permutation of string?

前端 未结 20 1641
醉话见心
醉话见心 2020-11-27 11:15
void permute(string elems, int mid, int end)
{
    static int count;
    if (mid == end) {
        cout << ++count << \" : \" << elems << end         


        
20条回答
  •  情书的邮戳
    2020-11-27 11:36

    Even I found it difficult to understand that recursive version of the first time and it took me some time to search for a berre way.Better method to find (that I can think of) is to use the algorithm proposed by Narayana Pandita. The basic idea is:

    1. First sort the given string in no-decreasing order and then find the index of the first element from the end that is less than its next character lexicigraphically. Call this element index the 'firstIndex'.
    2. Now find the smallest character which is greater thn the element at the 'firstIndex'. Call this element index the 'ceilIndex'.
    3. Now swap the elements at 'firstIndex' and 'ceilIndex'.
    4. Reverse the part of the string starting from index 'firstIndex+1' to the end of the string.
    5. (Instead of point 4) You can also sort the part of the string from index 'firstIndex+1' to the end of the string.

    Point 4 and 5 do the same thing but the time complexity in case of point 4 is O(n*n!) and that in case of point 5 is O(n^2*n!).

    The above algorithm can even be applied to the case when we have duplicate characters in the string. :

    The code for displaying all the permutation of a string :

    #include 
    
    using namespace std;
    
    void swap(char *a, char *b)
    {
        char tmp = *a;
        *a = *b;
        *b = tmp;
    }
    
    
    int partition(char arr[], int start, int end)
    {
        int x = arr[end];
        int i = start - 1;
        for(int j = start; j <= end-1; j++)
        {
            if(arr[j] <= x)
            {
                i = i + 1;
                swap(&arr[i], &arr[j]);
            }
        }
        swap(&arr[i+1], &arr[end]);
        return i+1;
    }
    
    void quickSort(char arr[], int start, int end)
    {
        if(start= str[firstIndex] && str[i] <= str[ceilIndex])
                ceilIndex = i;
        }
        return ceilIndex;
    }
    
    void reverse(char *str, int start, int end)
    {
        while(start<=end)
        {
            char tmp = str[start];
            str[start] = str[end];
            str[end] = tmp;
            start++;
            end--;
        }
    }
    
    void permutate(char *str, int n)
    {
        quickSort(str, 0, n-1);
        cout << str << endl;
        bool done = false;
        while(!done)
        {
            int firstIndex;
            for(firstIndex = n-2; firstIndex >=0; firstIndex--)
            {
                if(str[firstIndex] < str[firstIndex+1])
                    break;
            }
            if(firstIndex<0)
                done = true;
            if(!done)
            {
                int ceilIndex;
                ceilIndex = findCeilIndex(str, firstIndex, n);
                swap(&str[firstIndex], &str[ceilIndex]);
                reverse(str, firstIndex+1, n-1);
                cout << str << endl;
            }
        }
    }
    
    
    int main()
    {
        char str[] = "mmd";
        permutate(str, 3);
        return 0;
    }
    

提交回复
热议问题