2

I came into the problem when I have a given sequence s=(a,b,c,d,e...) - sorted in non-decreasing order. My job is to develop an algorithm that is going to generate all possible permutations in lexicographical order - ending on the reversed s (highest in order).

The trick is: I cannot compare any 2 element to each other. All operations must be done "automatically", regardless of elements values.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
maciek
  • 1,807
  • 2
  • 18
  • 30
  • Either you need to compare the elements to judge which ones are equal, or you must be allowed to output duplicate strings. – aioobe Jan 11 '15 at 20:17
  • Ok then step through the permutations of 1..n, and apply the permutation to s only when outputting. But perhaps that violate the spirit of this question. Why does that restriction exist? – harold Jan 11 '15 at 20:19
  • Okay, I will output duplicate strings, in case there are equal elements in s. – maciek Jan 11 '15 at 20:20
  • @harold : I do not understand your solution... Could you be more precise ? – maciek Jan 11 '15 at 20:22
  • @maciek in an extra array you generate all the permutations of 1..n, you can do that the standard way because no elements from s are involved so the restriction of comparisons does not apply. Then for each permutation, use it to construct the corresponding permutation of elements from s. – harold Jan 11 '15 at 20:25
  • All that's needed is then a "standard" algorithm for generating permutations in lexicographical order. Perhaps the common/naive algorithms generate permutations in lexicographical order? – aioobe Jan 11 '15 at 20:27
  • How do you define lexicographical order in this problem? A standard definition requires elements to be comparable. – kraskevich Jan 11 '15 at 20:42
  • @harold : In fact my elements {a,b,c...} are integers {1,2,3...} that is not a solution I am looking for. I look for another algorithm, not a shortcut. – maciek Jan 11 '15 at 20:42
  • @aioobe : as I see all these "standard" algorithms include comparing elements values - thats the problem. – maciek Jan 11 '15 at 20:43
  • @ILoveCoding : order is defines as usual, the elements are comparable. The algorithm must not compare them. I start from the lowest permutation, finish at the highest. The algorithm should swap items regardles of their values. – maciek Jan 11 '15 at 20:44
  • Have a look at http://rosettacode.org/wiki/Permutations_by_swapping Keep in mind that based on your input {1,2,3...} you can construct a list of pairs {(1,a),(2,b),(3,c),...} where the accompanying element is comparable. – aioobe Jan 11 '15 at 20:51
  • Thanks @aioobe, I have seen this already - these are not in the order. – maciek Jan 11 '15 at 20:58

1 Answers1

1

You can do it this way:

// n is the number of elements in the given sequence
p = all permutations of [0, 1, ..., n - 1] in lexicographical order    
for permutation in p:  
        for i = 0 ... n - 1
            print(s[permutation[i]]) // s is the given sequence

You can generate all permutations of [0, 1, ..., n - 1] using any standard algorithm(recursively or starting with {0, 1, ..., n - 1} and generating the next permutation n! - 1 times). Actually, a standard recursive algorithm for generating all permutations applied directly to the given sequence will generate them in right order(and it does not require comparing elements).

Here is pseudo code of recursive algorithm:

// Generates all permutations recursively
// permutation - a prefix of an arbitrary permutation
// sequence - the input sequence
// used - a boolean array where used[i] = true if and only if
// an element with index i is already in permutation
def generatePermutations(permutation, sequence, used)
    if permutation.length() == sequence.length()
        // The permutation is fully generated
        print(permutation)
    else
        // Adds all elements that are not present in permutation yet.
        // Starts with the smallest index to maintain the correct order.
        for i = 0 ... sequence.length() - 1
            if not used[i]
                used[i] = true
                permutation.push_back(sequence[i])
                generatePermutations(permutation, sequence, used)
                used[i] = false
                permutation.pop_back()

sequence = input()
permutation = an empty list
used = array of sequence.length() elements filled with a
generatePermutations(permutation, sequence, used)
kraskevich
  • 18,368
  • 4
  • 33
  • 45
  • Are you sure it will be right order ? As here: http://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/ the last 2 elements are out of order. – maciek Jan 12 '15 at 18:39
  • @maciek When I mentioned a standard recursive algorithm, I meant something like: for all numbers that are not added yet, append it the end and keep going recursively, not the algorithm in a link you've posted. – kraskevich Jan 12 '15 at 19:00
  • Thats exactly what I am looking for - what is the algorithm for recursive generations of {0...n-1} without comparison of elements. The main idea of my question lies within this "standard algorithm". I do not want shortcuts like "permute numbers and print corresponding strings" – maciek Jan 12 '15 at 20:16
  • @maciek I have added a pseudo code for recursive generation. – kraskevich Jan 12 '15 at 20:29
  • Thank you @ILoveCoding, I have rewritten it in Python and it worked :) Now I have to understand: why? – maciek Jan 12 '15 at 21:09