I want a class, that take in a possitive integer and produce a iterator that let me iterate through all possible of permutation of a list of possitive numbers under the positive integer.
eg. permulator p = paermulator(3)
p.next() -> [0,1,2]
p.next() -> [0,2,1]
p.next() -> [1,0,2]
p.next() -> [1,2,0]
...
which is 6 possible permutations in this case.
I have designed a class, but it is incredibly slow, I want to make iterate faster.
This is my design:
(I am doing it pruely for that sake that it seems possible. )
package Mathematica.complexity;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
/**
* Tthis will be a class that demonstrate what we call:
* a factorial complexity algorithm
* it's going to print all the possible permutations of some sort of collection
* in java.
* <br>
* A recursive data structure that resembles the process of permutating.
* @author dashie
*
*/
public class FactorialComplexity implements Iterator<List<Integer>>
{
private List<Integer> G_Data;
// sub recursive structure of the class.
private FactorialComplexity G_next = null;
private int G_ChoosenIndex = 0;
private boolean G_canProduceNextElement= true;
public static void main(String[] args)
{
}
public FactorialComplexity(int NumbersofElements)
{
if(NumbersofElements <0)throw new AssertionError();
this.G_Data = new LinkedList<>();
for(int i =0; i< NumbersofElements;i++)this.G_Data.add(i);
this.prepareSubStructure();
}
protected FactorialComplexity(List<Integer> argIn)
{
this.G_Data = argIn;
this.prepareSubStructure();
}
/**
* Using the internal index to return the current element it is
* pointing at.
* <br></b>I doesn't increment the internal pointer. </b>
* @return
*/
public Integer getChoosenElement()
{
//if(this.G_Data.size() == 0)return null;
return this.G_Data.get(this.G_ChoosenIndex);
}
/**
* This function serves for the iterator.
* @return
*/
public List<Integer> getPermutation()
{
// two of the base case.
if(this.G_Data.size()==0)
{
return new LinkedList<>();
}
if(this.G_Data.size()==1)
{
List<Integer> temp = new LinkedList<>();
temp.add(this.G_Data.get(0));
return temp;
}
return this.getPermutation_part1(new LinkedList<Integer>());
}
private List<Integer> getPermutation_part1(List<Integer> argIn)
{
argIn.add(getChoosenElement());
argIn.addAll(this.G_next.getPermutation());
return argIn;
}
/**
* <ol>
* <li>If the sub-structure has next element, increment the sub structure.
* <li>If not, increment the index in this instance and recreate sub structure.
* <li>be careful about the base case please.
* </ol>
*
* @return
* if this, including sub structure should be incremented.
*
*/
protected boolean increment()
{
if(this.G_next!= null)
{
boolean temp = this.G_next.increment();
int pointer = this.G_ChoosenIndex;
if(this.G_ChoosenIndex+1<this.G_Data.size())
{
if(temp)
{
this.G_ChoosenIndex++;
this.prepareSubStructure();
}
return false;
}
else
{
return (this.G_ChoosenIndex+1 == this.G_Data.size())&&temp;
}
}
else
{
//empty means not choice can make.
return true;
}
}
@Override
/**
* All the nodes are at its last index.
*/
public boolean hasNext()
{
if(!this.G_canProduceNextElement)return false;
if(this.isAllPointingAtLastIndex())this.G_canProduceNextElement=false;
return true;
}
/**
* This index in this class instance and
* all its sub structure are pointing at the last index?
* @return
*/
boolean isAllPointingAtLastIndex()
{
if(this.G_Data.size()<=1)
{
return true;
}
return this.G_ChoosenIndex+1
==
this.G_Data.size()&&this.G_next.isAllPointingAtLastIndex();
}
@Override
public List<Integer> next()
{
List<Integer> result = this.getPermutation();
this.increment();
return result;
}
public String toString()
{
String s = new String();
s+= this.G_Data+":"+this.G_ChoosenIndex+"->";
if(this.G_next!= null)s+= this.G_next.toString();
return s;
}
/**
* <ol>
* <li>Base case: the list in this instant is empty.
* <li>Make a copy of the local collection, excluding the
* element the pointer is pointing to
* <li>Make connect the this object to its sub structure and recurse.
* </ol>
*/
protected void prepareSubStructure()
{
if(this.G_Data.size() == 0)return;
List<Integer> temp = new LinkedList<>();
temp.addAll(this.G_Data);
temp.remove(this.G_ChoosenIndex);
this.G_next = new FactorialComplexity(temp);
this.G_next.prepareSubStructure();
}
public static int factorial(int n)
{
if(n<0)return 0;
if(n<=1)return 1;
return n*factorial(n-1);
}
}
To summarize: The class is recursive like a linked list, each node contains the an index that indicate the element it is pointing at and a list of all the element got passed from the previouse node.
How Naive is this approach? How can I make it faster?