显然,您的两个解决方案都违反了问题条件,第一个解决方案在第一行和第六行重复了 1 和 5 的序列,第二个解决方案在第二和第九行重复了 2 和 7 的序列,但是还是很有趣的。
我创建了这段代码来实现您正在寻找的算法,我希望这不会浪费我的时间。
这足以证明问题可以通过编程方式解决。
该算法包含三个重要的方法。
order_accepted(ArrayList reslist, int c)
搜索我们目前得到的列表,并在之前生成的列表中的列表(我们现在正在构建的)的任何元素之后发生 c 时返回 false。
buildlist(ArrayList reslist, int siz_r, int[] arr)
在不违反我们的条件的情况下建立一个列表,当然是使用前面的方法来检查。
lists_start_with(int c, int siz_r, int[] arr)
我们使用它来避免丢失以相同数字开头的列表,我们应该这样做,否则我们将得到不超过一个以任何元素开头的列表(如果存在的话),我们不能得到两个。
build_solution(int[] arr, int siz_r)
您需要此函数为每个输入数字调用先前的方法,以获取所有列表以它开头并将它们添加到解决方案中。
要获得解决方案,请在 main 方法中设置输入数组 a 和大小 r,如:
ag.build_solution(new int[]{1,2,3,....},r=..);
解决方案:
a={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, r=17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
14 13 12 11 10 9 8 7 6 5 4 3 2 1 18 19 20
a={1,2,3,4,5}, r=4
1 2 3 4
3 2 1 5
a={1,2,3,4,5,6,7,8,9}, r=4
1 2 3 4
1 5 6 7
2 1 8 9
2 7 6 5
3 5 8 1
3 6 9 2
4 5 9 3
4 7 8 2
7 9 4 1
a={1,2,3,4,5,6,7,8,9}, r=3
1 2 3
1 4 5
1 6 7
1 8 9
2 4 1
2 5 6
2 7 8
3 2 9
3 4 6
3 5 1
3 8 7
4 7 2
4 8 3
5 4 9
5 7 3
5 8 2
6 8 1
6 9 2
7 6 4
7 9 1
8 6 5
9 6 3
9 7 5
9 8 4
a={1,2,3,4,5,6,7,8,9}, r=6
1 2 3 4 5 6
3 2 1 7 8 9
5 4 9 8 7 1
代码:
类算法:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Alg {
public static List<Object> solut = new ArrayList();
@SuppressWarnings("rawtypes")
public boolean order_accepted(ArrayList reslist, int c) {
boolean result = true;
if ((solut != null) && (solut.size() > 0)) {
Iterator iter = solut.iterator();
// for every list in this solution
while (iter.hasNext()) {
ArrayList temp = (ArrayList) iter.next();
if (temp != null && temp.size() > 0)
// for every element in our current list
for (int el = 0; el < reslist.size(); el++)
// for every element in this list of our solution
for (int j = 0; j < temp.size(); j++)
if (temp.get(j).equals(reslist.get(el))) {
// start looking for c in this list of our
// solution
for (int k = j; k < temp.size(); k++) {
if (temp.get(k).equals(c)) // if you find c
// then it
// is after; so will not
// be after any more;
// drop c.
return false;
}
break;
}
}
}
return result;
}
public boolean is_in_list(int c, ArrayList lst) {
boolean res = false;
if (lst != null)
for (int i = 0; i < lst.size(); i++)
if ((Integer) lst.get(i) == c) {
res = true;
break;
}
return res;
}
public ArrayList copylist(ArrayList lst) {
ArrayList res = null;
if (lst != null) {
res = new ArrayList();
for (int i = 0; i < lst.size(); i++) {
res.add(lst.get(i));
}
}
return res;
}
// we call this method after we set the first element of the list and
// (recursively),
// to get the next (r-1) elements from the input array (arr).
@SuppressWarnings("unchecked")
public boolean buildlist(ArrayList reslist, int siz_r, int[] arr) {
boolean full = false;// this variable determine whether we added an
// element to this reslist or no available
// element found
if (reslist.size() < siz_r) {
for (int i = 0; i < arr.length; i++) {
// if arr[i] is not in the current list and,
// its order (after) every element is accepted (never happened
// in the solution).
if (!is_in_list(arr[i], reslist)
&& order_accepted(reslist, arr[i])) {
reslist.add(arr[i]);
if (reslist.size() == siz_r)// list is full
{
full = true;
break;
}
else
{
//if fill with others is possible
ArrayList tmp=copylist(reslist);
if(buildlist(tmp,siz_r,arr))
{
return buildlist(reslist,siz_r,arr);
}
//else remove this element
//and continue searching for others.
else
{
reslist.remove(reslist.size()-1);
}
}
}// endif
}// endfor
return full;
} else
return true;
}
public void listes_start_with(int c, int siz_r, int[] arr) {
// Don't start with other numbers when you still have other listes start
// withe the same number, Example:
// arr{1,2,3,4,5} r=3 => (1) 2 3; (1) 4 5; 2 4 1; ...
// Note that only sub set of size One could be repeated in the same
// order (relatively); ({12}3; {12}4 are wrong listes).
boolean possible = true;// the possibility of finding other listes start
// with c by the result of buildlist method.
while (possible) {
ArrayList ls = new ArrayList();
ls.add(c);
if (c == 2) {
int x = 0;
x += 1;
}
if (buildlist(ls, siz_r, arr))
solut.add(ls);
else
possible = false;
}
}
public void build_solution(int[] arr, int siz_r) {
for (int i = 0; i < arr.length; i++) {
listes_start_with(arr[i], siz_r, arr);
}
}
@SuppressWarnings("rawtypes")
public void showsolution() {
for (int i = 0; i < solut.size(); i++) {
ArrayList temp = (ArrayList) solut.get(i);
if (temp != null && temp.size() > 0) {
for (int j = 0; j < temp.size(); j++) {
System.out.print(temp.get(j) + " ");
}
}
System.out.println("");
}
}
}
主类
public class Mclass {
public static void main(String args[])
{
Alg ag=new Alg();
ag.build_solution(new int[]{1,2,3,4,5,6,7,8,9},3);
ag.showsolution();
}
}
扩展算法以包含解决方案中的所有常见子集,我认为最好为此创建一个单独的子集。
我无法从数学上证明解决方案中可能的列表数量。
甚至是解决方案的总数,因为我只知道(在此算法中)当您对输入数组进行不同排序时,您会得到不同的解决方案。