Intuitively, you can obtain a new arrangement by exchanging any adjacent two elements in the array. For example, you can obtain the positions of 5 and 4 in the array [, 5], [, 4], and then change the positions of 5 and 3 to [, 3, 4]…… In this way, can all (non-repeated) Orders be obtained without interruption? There are two problems:
1) How can we obtain all the permutation by exchanging two adjacent elements (or sometimes we need to exchange non-Adjacent Elements )?
2) in what order do elements need to be exchanged to ensure that new (non-repeated) elements are arranged each time?
Switching the positions 4, 3, 2, and 1 in sequence of 5 is equivalent to inserting 5 into all possible positions of the subarray [1, 2, 4] to get a new arrangement. If we already know all the arrays of the sub-array [1, 2, 3, 4], We can insert 5 to all possible positions of these arrays to obtain the arrays [1, 2, 3, 4, 4, 5. So how can we know all the arrays in the subarray [1, 2, 3, 4? We can also break [,] into 4 and sub-arrays [, 3]… In this way, the sub-array is decomposed until there is only one element left. Based on this idea, we will get a general recursive algorithm to generate a fully arranged algorithm. However, the bitwise method uses another idea: to add a moving direction to each element.
View sourceprint? Class Item
{
Public Item (string value, Item [] container, int index)
{
Value = value;
Direction = ItemDirection. Left; // The default Direction at the initial time is to the Left.
}
// Element value
Public string Value {get; set ;}
// The moving direction of the element
Public ItemDirection Direction {get; set ;}
}
Enum ItemDirection
{
Left = 0,
Right = 1
}
With this moving direction, the rule of the bitwise swap method becomes extremely simple:
1) if the moving direction of an element is smaller than that of it, the element is movable. On the contrary, if the moving direction of an element is greater than that of it, the element cannot be moved. If an element is not moved to a forward position, the element cannot be moved.
2) each time, we first look for the largest movable element max, exchange it with the moving direction of the adjacent position, and then reverse the movement direction of all elements larger than max.
3) Repeat (2) until all elements cannot be moved.
The following shows the process of generating the first 27 arrays in the array [1, 2, 3, 4, 5] using the bitwise transform method.
The source code is as follows.
View sourceprint? Class Program
{
Static void Main (string [] args)
{
String [] source = new string [] {"1", "2", "3", "4", "5 "};
Foreach (IList <string> p in SwapPermutation (source ))
{
Console. WriteLine (p. Montage (t => t ,""));
}
}
// Use the forward transform method to generate a full ranking
Static IEnumerable <IList <string> SwapPermutation (string [] source)
{
Yield return source. ToList (); // The first arrangement is the initial order of the array.
Vertex list <Item> s = Item. Create (source); // Initialization
Item max = null;
While (max = FindMaxMovableItem (s ))! = Null) // find the largest removable element max
{
Max. Move (); // swap max with the forward position
Yield return s. ToList (t => t. Value); // a new arrangement is generated after the switch.
// Reverse the movement direction of all elements greater than max
Foreach (Item item in s)
{
If (item> max)
Item. ReverseDirection ();
}
}
}
// Find the largest movable element. If no value is found, null is returned.
Static Item FindMaxMovableItem (optional list <Item> s)
{
Item max = null;
Foreach (Item item in s)
{
If (item. IsMovable () & (max = null | item> max ))
Max = item;
}
Return max;
}
}
The complete code of Item is as follows.
View sourceprint? // Element with a direction
[DebuggerDisplay ("Value = {Value} Direction = {Direction} Index = {Index}")]
Class Item
{
Public Item (string value)
{
Value = value;
Direction = ItemDirection. Left; // The default Direction at the initial time is to the Left.
}
// Element value
Public string Value {get; set ;}
// The moving direction of the element
Public ItemDirection Direction {get; set ;}
// Nodes in the linked list
Public writable listnode <Item> Node {get; set ;}
// Initial creation
Public static shortlist <Item> Create (string [] source)
{
Shortlist <Item> result = new shortlist <Item> ();
For (int I = 0; I <source. Length; I ++)
{
Item item = new Item (source [I]);
// Add a reverse reference to the node in the linked list so that you can know what the previous and next nodes are.
Item. Node = result. AddLast (item );
}
Return result;
}
// Reverse the moving direction of the element
Public void ReverseDirection ()
{
If (Direction = ItemDirection. Left)
& Nb