Algorithm 从键盘输入所有可能的数字

Algorithm 从键盘输入所有可能的数字,algorithm,graph,Algorithm,Graph,我试图解决这个问题: 1 2 3 4 5 6 7 8 9 * 0 # 给定起始号码,尽可能找到所有6位数的号码,只能水平或垂直拨号。不允许重复。数字不能从零开始,并且不包括*和#。例如,如果上次拨打的号码是3,则下一个号码可能是1、2、6或9 我试图通过创建一个图来实现这一点,在这个图中,一个数字只有相邻的那些在同一行和同一列中的数字,然后从起始数字开始寻找长度为5的所有可能路径。但我还不知道做这件事的算法 有什么建议吗?假设数字存储在二维数组NUMPAD,其中“1”位于索引[

我试图解决这个问题:

1  2  3
4  5  6
7  8  9
*  0  #
给定起始号码,尽可能找到所有6位数的号码,只能水平或垂直拨号。不允许重复。数字不能从零开始,并且不包括*和#。例如,如果上次拨打的号码是3,则下一个号码可能是1、2、6或9

我试图通过创建一个图来实现这一点,在这个图中,一个数字只有相邻的那些在同一行和同一列中的数字,然后从起始数字开始寻找长度为5的所有可能路径。但我还不知道做这件事的算法


有什么建议吗?

假设数字存储在二维数组
NUMPAD
,其中“1”位于索引[0][0],“2”位于索引[0][1]等等

Func permute_nums(digits_so_far)
    If digits_so_far has 6 elements
        print digits_so_far
        return
    Let L = last element of digits_so_far
    Find index (x,y) of L in NUMPAD
    For i from -2 to +2
        if (x+i,y) is NOT out of bounds
            Find number n at (x+i,y)
            permute_nums(digits_so_far + [n])
        if (x,y+i) is NOT out of bounds
            Find number m at (x,y+i)
            permute_nums(digits_so_far + [m])

给定起始数字,我认为你走的路是对的。 只需遍历树(标记每个访问的节点,以避免重复),并输出每个长度为5的路径


在这里你不需要什么新东西,即使是深度5的基础也可以。

hmmm。这应该很容易

static var a:Array=[[8],[2,4],[1,3,5],[2,6],[1,5,7],[2,4,6,8],[3,5,9],[4,8],[5,7,9,0],[6,8]];
function giveAllnumbers(numbersSoFar:String,lastSelectedNumber:int,:int) {
    if (howManyToSelectLeft==0) {
        trace(numbersSoFar); // output goes here
        return;
    }
    for (var i:int=a[lastSelectedNumber].length-1;i>=0;i--) 
        giveAllNumbers(numbersSoFar+a[lastSelectedNumber][i].toString(),
            a[lastSelectedNumber][i],
            howManyToSelectLeft-1);
}

这是Actionscript,但可以适应任何其他语言。调用时使用
giveAllNumbers(“”+yourNumber.toString(),yourNumber,desiredLength)

此问题可以递归解决,返回点将在length==6时

private static void countMaxNumbers(String i) {
    if(i.length() == 6)
    {
        numberCount++;
        return;
    }
    if(i.charAt(i.length() - 1) == '1'){
        countMaxNumbers(i+'2');
        countMaxNumbers(i+'3');
        countMaxNumbers(i+'4');
        countMaxNumbers(i+'7');
    }
    else if(i.charAt(i.length() - 1) == '2'){
        countMaxNumbers(i+'5');
        countMaxNumbers(i+'8');
        countMaxNumbers(i+'0');
        countMaxNumbers(i+'1');
        countMaxNumbers(i+'3');
    }
    else if(i.charAt(i.length() - 1) == '3'){
        countMaxNumbers(i+'1');
        countMaxNumbers(i+'2');
        countMaxNumbers(i+'6');
        countMaxNumbers(i+'9');
    }
    else if(i.charAt(i.length() - 1) == '4'){
        countMaxNumbers(i+'1');
        countMaxNumbers(i+'7');
        countMaxNumbers(i+'5');
        countMaxNumbers(i+'6');
    }
    else if(i.charAt(i.length() - 1) == '5'){
        countMaxNumbers(i+'2');
        countMaxNumbers(i+'8');
        countMaxNumbers(i+'0');
        countMaxNumbers(i+'4');
        countMaxNumbers(i+'6');
    }
    else if(i.charAt(i.length() - 1) == '6'){
        countMaxNumbers(i+'3');
        countMaxNumbers(i+'9');
        countMaxNumbers(i+'4');
        countMaxNumbers(i+'5');

    }
    else if(i.charAt(i.length() - 1) == '7'){
        countMaxNumbers(i+'1');
        countMaxNumbers(i+'4');
        countMaxNumbers(i+'8');
        countMaxNumbers(i+'9');

    }else if(i.charAt(i.length() - 1) == '8'){
        countMaxNumbers(i+'7');
        countMaxNumbers(i+'9');
        countMaxNumbers(i+'2');
        countMaxNumbers(i+'5');
        countMaxNumbers(i+'0');
    }else if(i.charAt(i.length() - 1) == '9'){
        countMaxNumbers(i+'3');
        countMaxNumbers(i+'6');
        countMaxNumbers(i+'7');
        countMaxNumbers(i+'8');
    }else if(i.charAt(i.length() - 1) == '0'){
        countMaxNumbers(i+'2');
        countMaxNumbers(i+'8');
        countMaxNumbers(i+'5');
    }
}

答案应该是:12855

“出界”=在NUMPAD之外,或者对应于*或#我假设“不重复”只意味着同一个数字不能连续出现两次(例如,122345不好,但123245可以)。如果6位数字的每个数字都必须是唯一的,那么除了“越界”检查外,我们还需要检查数字n(或m)是否已经在数字\u sou\u中。但是数字\u sou\u的大小不会无限增长吗?当元素有6位数字时,不需要删除元素吗?不,它是递归的,在函数的顶部,当它达到6位数字时,你会看到它停止递归。for循环负责迭代所有可能的第二位数字,然后(一级递归之后)迭代所有可能的第三位数字,等等。我说,因为我使用了一个指向数组数字的指针,其大小是一个整数,所以递归没有什么区别。