假设有个集合拥有m个元素,任意的从集合中取出n个元素,则这n个元素所形成的可能子集有那些?
假设有5个元素的集点,取出3个元素的可能子集如下:
这些子集已经使用字典顺序排列,如此才可以观察出一些规则:
所以关键点就在于哪一个位置必须进行加1的动作,到底是最右一个位置要加1?还是其它的位置?
在实际撰写程式时,可以使用一个变数positon来记录加1的位置,position的初值设定为n-1,因为我们要使用阵列,而最右边的索引值为最大的n-1,在position位置的值若小于m就不断加1,如果大于m了,position就减1,也就是往左移一个位置;由于位置左移后,右边的元素会经过调整,所以我们必须检查最右边的元素是否小于m,如果是,则position调整回n-1,如果不是,则positon维持不变。
假设有5个元素的集点,取出3个元素的可能子集如下:
{1 2 3}、{1 2 4 }、{1 2 5}、{1 3 4}、{1 3 5}、{1 4 5}、{2 3 4}、{2 3 5}、{2 4 5}、{3 4 5}
这些子集已经使用字典顺序排列,如此才可以观察出一些规则:
- 如果最右一个元素小于m,则如同码表一样的不断加1
- 如果右边一位已至最大值,则加1的位置往左移
- 每次加1的位置往左移后,必须重新调整右边的元素为递减顺序
所以关键点就在于哪一个位置必须进行加1的动作,到底是最右一个位置要加1?还是其它的位置?
在实际撰写程式时,可以使用一个变数positon来记录加1的位置,position的初值设定为n-1,因为我们要使用阵列,而最右边的索引值为最大的n-1,在position位置的值若小于m就不断加1,如果大于m了,position就减1,也就是往左移一个位置;由于位置左移后,右边的元素会经过调整,所以我们必须检查最右边的元素是否小于m,如果是,则position调整回n-1,如果不是,则positon维持不变。
public
class
NofM
... {
private int m;
private int[] set;
private boolean first;
private int position;
public NofM(int n, int m)
...{
this.m = m;
first = true;
position = n - 1;
set = new int[n];
for(int i = 0; i < n; i++)
set[i] = i + 1;
}
public boolean hasNext()
...{
return set[0] < m - set.length + 1;
}
public int[] next()
...{
if(first)
...{
first = false;
return set;
}
if(set[set.length-1] == m)
position--;
else
position = set.length - 1;
set[position]++; // 调整右边元素
for(int i = position + 1; i < set.length; i++)
set[i] = set[i-1] + 1;
return set;
}
public static void main(String[] args)
...{
NofM nOfm = new NofM(4, 9);
while(nOfm.hasNext())
...{
int[] set = nOfm.next();
for(int i = 0; i < set.length; i++)
...{
System.out.print(set[i]);
}
System.out.println();
}
}
}
... {
private int m;
private int[] set;
private boolean first;
private int position;
public NofM(int n, int m)
...{
this.m = m;
first = true;
position = n - 1;
set = new int[n];
for(int i = 0; i < n; i++)
set[i] = i + 1;
}
public boolean hasNext()
...{
return set[0] < m - set.length + 1;
}
public int[] next()
...{
if(first)
...{
first = false;
return set;
}
if(set[set.length-1] == m)
position--;
else
position = set.length - 1;
set[position]++; // 调整右边元素
for(int i = position + 1; i < set.length; i++)
set[i] = set[i-1] + 1;
return set;
}
public static void main(String[] args)
...{
NofM nOfm = new NofM(4, 9);
while(nOfm.hasNext())
...{
int[] set = nOfm.next();
for(int i = 0; i < set.length; i++)
...{
System.out.print(set[i]);
}
System.out.println();
}
}
}