Combination object,AlgorithmWhen I was just learning this lesson, I also looked down on him. Then he realized his importance when writing algorithms, especially the brute force method.
Let's talk about his usefulness first. Some combination problems are often encountered in algorithm problems, such:
Here is a set of S = {2, 7, 36, 40, 53, 59, 62, 69, 77, 80, 87, 89, 95, 98,100,102,103,106,112,115 }, you need to find the subset T from s so that the sum of all elements in T is 220.
Of course, this problem can not only be solved by brute force. But if we use the brute force method, is there any simple way to make the algorithm more efficient. This requires a composite object.
The combination object x = {Xi}. In my understanding, it is a set with the same number of elements as the set S = {Si}, and X corresponds to the elements in s one by one, each element in X has only two values, A and B. When xi = A, Si is selected; When xi = B, Si is not selected. (In most cases, a = 1, B = 0 by default)
This is an example of a composite object. T is a subset of the complete set S = {1, 2, 3}. It is determined by the value of the composite object.
We can see that if we can have a method to generate all the combined objects in an iterative order, it is much easier to select different subsets of the complete set S. And now there have been a lot of research results from cool people. using their algorithms is definitely easier than ourselves. The key is high efficiency.
The following describes lexicographic ordering and gray codes. The examples are the complete set of S, T as the subset, and | S |=| t |= 3. The element index increases from left to right, and the first index is 0.
Lexicographic ordering
{0, 0, 1}
{0, 1}
{0, 1}
{1, 0, 0}
{1, 0, 1}
{1, 1, 0}
{1, 1}
{0, 0}
Algorithm idea: each time the pointer starts scanning from the right to the left:// Take {0, 0, 1} As An Example
(1)Every encounter1, change it to 0, and continue to scan the next position to the left, that is, the Pointer Points to the next position;// Change the combination object to {0,0, 0}, pointer to Red Element
(2) If the pointer index is-1, {, 1}, the algorithm ends;// If {, 1} is used as an example, the combination object is {0, 0}, and the algorithm ends.
(3) Otherwise, change the pointer to 1 and end the scan;// Example in (1): At this time, the element indicated by the pointer is changed to 1, that is, {0,1, 0}, which is the next composite object
The following composite object is obtained.
The following areCodeFor reference:
Public Boolean [] Next () {If (! Hasnext) return NULL; // The combined object is generated. Int Index = n-1; while (index> = 0 & set [Index]) {set [Index] = false; index --;} If (Index =-1) {hasnext = false;} else {set [Index] = true;} return set ;}
Gray Codes
{0, 0}
{0, 0, 1}
{0, 1}
{0, 1}
{1, 1, 0}
{1, 1}
{1, 0, 1}
{1, 0, 0}
Algorithm idea: As shown in, the generation of composite objects follows a fixed pattern, that is, the border of the drawn image changes in a "-" shape:
(1) When going up or down in a straight line, only the rightmost one is used for reverse operation, that is, the next composite object;
(2) When following a straight line to the right (to the left, and so on ):
A. When the inverse operation in (1) is set to 0 and set to 1, you only need to reverse the second position on the right to obtain the next composite object;
B. otherwise, the index I of the first 1 is found from the right-to-left scan. If I = 0, that is, I is the leftmost index, there is no longer a composite object, and the algorithm ends, otherwise, the position I-1 is reversed to the next composite object;
The Code is as follows for your reference only:
// Array index from 0 to npublic Boolean [] Next () {If (BEGIN) {// if it is the first time to call begin = true, {0, 0, 0 ,..., 0} begin = false; return set;} If (! Hasnext) return NULL; // if no combination object is returned, null if (turnflag) {// If (! Set [N]) {set [N] =! Set [N]; // 0 changes to 1 Index = n-1;} else {set [N] =! Set [N]; // 1 to 0 Index = n-1; while (! Set [Index]) index --; // if the current BIT is 0, move it to the left. If (Index = 0) {hasnext = false; // 100 at this time...} else {index --; // now it is... 100... next }}turnflag = false;} else {// move set [Index] = to the right! Set [Index]; turnflag = true;} return set ;}