【问题标题】:Java - How many combination of numbersJava - 有多少个数字组合
【发布时间】:2012-04-28 19:07:02
【问题描述】:

任何人都可以告诉我如何在 Java 中计算以下问题。多少个可能的有效数字,其中有效数字是 0-9 之间的任何数字,长度为 10 位,不包括 # 或 *,棋子在通过电话键盘时可以追踪。假设我有一个国王,它只能像在真正的游戏中一样向任何方向移动,但一次只能移动一个单元格。

所以键盘看起来像这样:

         1  2  3
         4  5  6
         7  8  9
         *  0  #

所以棋子每次移动 10 步,它创建的每个唯一数字都是有效数字。一块从最初的起始位置开始它的旅程。

更新: 一块可以移动或停留在一个地方(移动或停留都将被视为移动)以及重新访问单元格(只要其在各自的移动权限内允许)。因此,例如,如果国王从位置 1 移动,则创建有效数字的三个有效 10 步路径数字可能是 1236547890 或 1111111111 或 1212121212

这是一个小版本的四格方形垫的代码,只有 4 个格子,仅用于测试目的:

public class King
{
private static final Integer[] ALLOWED_FROM_1 = {2, 3, 4};
private static final Integer[] ALLOWED_FROM_2 = {1, 3, 4};
private static final Integer[] ALLOWED_FROM_3 = {1, 2, 4};
private static final Integer[] ALLOWED_FROM_4 = {1, 2, 3};
List<Integer> visited;

public King()
{
    this.visited = new ArrayList<Integer>();

}

public List<Integer> get_destinations(int currentPos, int noOfMoves)
{
    if (noOfMoves == 0)
    {
        visited.add(currentPos);
        return visited;

    }
    else
    {

        List<Integer> possibleMoves = getPossibleMoves(currentPos);

        for (int i = 0; i < possibleMoves.size(); i++)
        {
            visited.add(possibleMoves.get(i));
            get_destinations(possibleMoves.get(i), noOfMoves - 1);

        }

        return visited;
    }



}


private List<Integer> getPossibleMoves(int currentPos)
{

    List<Integer> possibleMoves = new ArrayList<Integer>();

    switch (currentPos)
    {
        case 1 : possibleMoves.addAll(Arrays.asList(ALLOWED_FROM_1));
            break;

        case 2: possibleMoves.addAll(Arrays.asList(ALLOWED_FROM_2));
            break;

        case 3 : possibleMoves.addAll(Arrays.asList(ALLOWED_FROM_3));
            break;

        case 4 : possibleMoves.addAll(Arrays.asList(ALLOWED_FROM_4));
    }

    return possibleMoves;

}
}

上面的代码只产生了部分答案,缺少许多不同的排列。主要问题是我如何才能确保它产生所有排列,以及在上面的代码中什么时候精确地到达应该存储和稍后检索的 4 位数字(在 4 次移动之后)。另外,我怎样才能避免重新访问相同的序列,例如 1234 1234 ,所以基本上优化它,这样它就不会产生相同的路径序列/有效数字。

非常感谢所有帮助。

【问题讨论】:

  • 什么棋子?这些中的任何一个?到目前为止,您尝试过什么?
  • 有固定的起始位置吗?
  • 听起来像是功课,如果是的话要加相应的标签吗?
  • 如果它不能重新访问一个单元格,则可以进行的最大移动数为 9(国王或王后)。

标签: java numbers combinations


【解决方案1】:

这里有一些伪代码可能会有所帮助。您可以使用以下方法递归地解决问题:

// Returns a list of all the destinations given a current location
// and the number of moves allowed (10 for King)
list<int> get_destinations(int cur_location, int num_moves) {
  // Base case. If no more moves are allowed, return current location as list.
  if(num_moves == 0) {
    return as_list(cur_location);
  } else {
    // List of all destinations possible from here
    list<int> destinations;
    // Get all the possible moves that are 1 step away.
    // For example: from 1, we would return 2 and 4
    list<int> possible_moves = get_possible_moves(cur_location);

    // For each of the moves generated from the last step,
    // recursively call get_destinations() with (num_moves - 1)
    for(int n:possible_moves) {
      destinations += get_destinations(n, num_moves - 1);
    }

    return destinations;
  }
}

然后你可以用这样的方式调用这个函数:

get_unique_nums(get_destinations); // Returns the set in the form you need it

祝你作业顺利!

【讨论】:

  • 谢谢 Mike .. 我尝试过类似的解决方案,但在递归中迷失了方向。我会用你的模板伪代码再试一次,然后告诉你它是怎么回事 ..
  • 我尝试过使用上述伪代码,但路径重复...我尝试使用较小的键盘,只有四个键 1,2,3,4 与 get_destinations(1, 4) .. 它返回 120/4 所以 30 个组合但是当检查时我看到重复的路径 .. 这里例如是前 4 个路径,你可以看到第二个和第四个是相同的 ->> 2, 1, 2, 1 , 3, 4, 3, 1, 2, 3, 4, 2, 3, 4, 3, 1 .. 我怎样才能防止这种情况发生
  • getPossibleMoves 是如何定义的?
  • 对不起..我已经包括了上面的 King 类的其余部分
  • @foofighter:当它应该返回当前元素时,您的基本情况返回空列表。此外,您似乎缺少 5+ 的案例。您目前放在那里的案例实际上似乎是错误的。当然,从 1 可以到达的实际上是 {2, 4, 5}
【解决方案2】:

似乎是相当微不足道的学术递归问题。只要允许递归,语言应该无关紧要。

你需要:

  1. 设置 一个。 F(n,m) 数组(在您的情况下值为 3x4) 湾。和一块的初始位置。 C。要允许任意片段,您可能需要定义定义允许移动的委托(函数指针,匿名类)函数

  2. 创建一个可递归调用的函数,用于识别下一个符合条件的仓位,并将其作为输入: 一个。当前棋子位置(i,j), 湾。第一次迭代的递归深度1

  3. 从深度=10的递归函数返回

  4. 如果您还需要所有序列,请将此递归函数设为可返回(非 void 类型)我会说字符串是最好的

  5. 如果您想让代码更简单,您不需要在允许的单元格集中的每一步验证 *、# 的存在,只需验证最后 10 个符号长的字符串是否可解析为 UNSIGNED LONG。虽然它使递归太长。

【讨论】:

  • 好的。但是为什么Return back from the recursive function on the depth = 10?。只要没有剩余有效动作(最多 10 个)就返回。
【解决方案3】:

对于国王来说,这种重复即将到来。 2, 1, 2, 1, 3, 4, 3, 1, 2, 3, 4, 2, 3, 4, 3, 1

您可以使 getPossibleMove() 函数以特定顺序返回单元格。 这将有助于避免路径重复。只按数字顺序说,它应该返回

2、1、2、1、
2, 1, 2, 3,
2, 1, 2, 5,
2, 1, 4, 1,
2, 1, 4, 5,
2、1、4、7

此外,如果您不想让棋子移动到同一个单元格,只需在 getPossibleMove() 函数中删除这些单元格即可。

我没有得到写什么代码,所以只写了理论解释。

【讨论】:

  • 嗨 Shashwat .. 感谢您的评论,是的,问题是什么特定的顺序 ..正如您从附加代码中看到的那样,我已将单元格按数字顺序排列,这就是我得到结果就像我们刚才描述的那样重复,我以前也有过..我真的希望昨晚能玩它,因为我今天需要尽快使用它,但是在过去几天的工作之后,我的睡眠变得更好了..所以酝酿新鲜的cuppa,并在我写作时试图让它发挥作用..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 2021-12-04
  • 2023-04-02
  • 2010-11-13
相关资源
最近更新 更多