在Java中为一个数字生成多个组合列表

在Java中为一个数字生成多个组合列表,java,arrays,list,multidimensional-array,Java,Arrays,List,Multidimensional Array,下面是我正在处理的问题和我的代码片段。 有没有更好的方法来实现这一点?我在下面使用了基本的控制结构 将行和列存储在映射中并基于键/值对在映射中搜索是否更好 大楼入口处有一个安全键盘。它有9个数字1-9,采用3x3矩阵格式 1 2 3 4.56 7 8 9 安全部门已决定允许一个人出现一个数字错误,但该数字应为水平或垂直。示例:对于5,允许用户输入2、4、6、8;对于4,允许用户输入1、5、7。如果要输入的安全代码为1478,并且如果用户输入1178,则应允许其输入 以下是我正在编写的代码片段:

下面是我正在处理的问题和我的代码片段。 有没有更好的方法来实现这一点?我在下面使用了基本的控制结构

将行和列存储在映射中并基于键/值对在映射中搜索是否更好

大楼入口处有一个安全键盘。它有9个数字1-9,采用3x3矩阵格式

1 2 3
4.56
7 8 9

安全部门已决定允许一个人出现一个数字错误,但该数字应为水平或垂直。示例:对于5,允许用户输入2、4、6、8;对于4,允许用户输入1、5、7。如果要输入的安全代码为1478,并且如果用户输入1178,则应允许其输入

以下是我正在编写的代码片段:

ArrayList<Integer> list = new ArrayList<Integer>();
int num = 9;
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};

for(int i =0;i< arr.length;i++){
  for(int j = 0; j <arr.length;j++){
    if(num == arr[i][j]){
      row = i;
      col = j;
      break;

    }
  }
}
for(int j1 = 0; j1< 3 ; j1++){
  if(arr[row][j1] != num){
    list.add(arr[row][j1]);
  }
}
for(int i1 = 0 ; i1 <3;i1++){
  if(arr[i1][col] != num){
    list.add(arr[i1][col]);
  }
}
ArrayList list=new ArrayList();
int num=9;
int[]arr={{1,2,3},{4,5,6},{7,8,9};
对于(int i=0;i对于(int j=0;j有很多方法可以解决这个问题,但我认为使用hashmap和hashset可以比多次迭代更有效地解决这个问题

如果我是你,我会首先使用哈希映射和哈希集构建数据模型。这是因为哈希映射和哈希集具有快速查找功能(无迭代)


我想要一个类似于
isCloseTo(inta,intb)
的函数,比如说,如果我调用
isCloseTo(5,5)
它将返回true。如果我调用
isCloseTo(2,5)
它也应该返回true。但是如果我调用
isCloseTo(1,3)
它将返回false

所以我会编写这样的测试:

assertTrue(isCloseTo(5,5));

好的,这很容易通过:

public boolean isCloseTo(int a, int b) {return true;}
那么,也许

assertFalse(isCloseTo(1,3));

上面的实现失败了,所以我需要更改它

public boolean isCloseTo(int a, int b) {return a == b;}
这仍然是一个不完整的实现,所以我们需要另一个测试

assertTrue(isCloseTo(1,2));


现在我们开始需要一些真正的实质内容。我想我会把剩下的留给读者作为一个练习。是的,我已经省略了一些棘手的部分,但这是一个策略(测试驱动设计)这将使您更直接地找到解决方案,而不仅仅是尝试编写代码。只要您通过所有测试,您就可以朝着完整的解决方案稳步前进。祝您好运!

这里有许多不同的可接受的解决方案。我想构造10x10整数矩阵来检查错误会更容易(例如errorMatrix)。第一个索引表示原始数字,第二个索引表示用户键入的数字,arr[i][j]的值表示此数字对的多个错误。以这种方式初始化:
errorMatrix[i][i]=0//无错误
errorMatrix[i][j]=1,其中i和j是水平或垂直相邻的数字
错误矩阵[i][j]=2,在其他情况下。

然后,对于每个数字对,您将得到O(1)中的错误数。您声明只接受一个错误,因此对于不匹配的数字对,2的值就足够了,您可以将错误数相加并与1进行比较。

那么,如何构造它。遍历所有的数字对并找到错误值。您最好实现函数CheckError,该函数将计算数字对a和b的错误值

  • 如果a=b,则误差矩阵为0;
  • 数字a和b是垂直的 如果abs(a-b)=3,那么是 abs(a-b)==3集误差矩阵[a][b]= 1、
  • 数字a和b是水平的 如果

    a、 (a-1)/3==(b-1)/3-这里我们检查这些数字是否在同一行上。
    b、 abs(a-b)=1-这里我们检查相邻单元格中是否有数字。
    如果是(a)和(b),则错误值为1;

  • 在其他情况下,错误值为2。

  • 在我看来,这个规范是正确的。但是,在使用

    因此,如果您想处理键盘布局的更改,只需重写CheckError方法。

    希望有帮助。

    或者这个

    boolean matchDigit(int p, int d) {
       return (p==d) 
           || (p==d-3) 
           || (p==d+3) 
           || (d%3!=1 && p==d-1) 
           || (d%3!=0 && p==d+1);
    } 
    

    这假设我们已经确定p和d在1和9之间。

    对于您问题中的特定键盘,我们可以使用基数3来解决此问题,并计算数字/键之间的距离

    1{1/3,1%3}={0,1}
    2{2/3,2%3}={0,2}

    5{5/3,5%3}={1,2}

    8{8/3,8%3}={2,2}

    public boolean isValidCode(int code, int expexted) {
        while(code > 0)
        {
            if (!isValidDigit(code % 10, expected % 10))
                return false ;
            code /= 10 ;
            expected /= 10 ;
        }
    
        return (code == expected) ;
    }
    
    public boolean isValidDigit(int a, int b) {
        int dx = (a - b) / 3 ;
        int dy = (a - b) % 3 ;
        return ((Math.abs(dx) + Math.abs(dy)) == 1)
    }
    
    一个更通用、更健壮的解决方案是创建一个映射,您可以在其中设置您接受的其他键

    示例:允许A、Z、p、M、N代表A:在映射中放置一个新条目“A”=“AZPMN”,验证检查d字符是否相同或类型字符是否在异常字符串中

    
    private Map acceptedChars = new HashMap() ;
    
    public void loadAcceptedCharacters() {
        acceptedChars.put('A', "AZPMN") ;
    }
    
    public boolean isValidKeyword(String word, String expected)
    {
        if (word == null || word.matches("\\s*"))
            return false ;
    
        if (word.length() != expected.length())
            return false ;
    
        for(int idx = 0; idx < word.length(); idx++)
        {
            if (!isValidDigit(word.chatAt(idx), expected.charAt(idx)))
                return false ;
        }
    
        return true ;
    }
    
    public boolean isValidDigit(char chr, char expected) {
        String accepted ;
        if (chr != expected)
        {
            accepted = acceptedChars.get(chr) ;
            if (accepted == null)
                return false ;
            if (accepted.indexOf(chr) < 0) 
                return false ;
        }
        return true ;
    }
    
    
    private Map acceptedChars=新HashMap();
    public void loadAcceptedCharacters(){
    承兑票据(A)和“AZPMN”);
    }
    公共布尔值isValidKeyword(字符串字,应为字符串)
    {
    if(word==null | | word.matches(“\\s*”))
    返回false;
    if(word.length()!=预期的.length())
    返回false;
    for(int idx=0;idx
    一件小事-您可以自由地重用
    i
    j
    ;它们的范围仅限于它们出现的循环。有多个循环非常常见,都使用
    i
    。我喜欢这个解决方案。但是,我不会将1放入一个值中,我只会使用映射来存储“可接受的错误”以便计数比较阶段中的“错误”。为什么使用映射
    public boolean isValidCode(int code, int expexted) {
        while(code > 0)
        {
            if (!isValidDigit(code % 10, expected % 10))
                return false ;
            code /= 10 ;
            expected /= 10 ;
        }
    
        return (code == expected) ;
    }
    
    public boolean isValidDigit(int a, int b) {
        int dx = (a - b) / 3 ;
        int dy = (a - b) % 3 ;
        return ((Math.abs(dx) + Math.abs(dy)) == 1)
    }
    
    
    private Map acceptedChars = new HashMap() ;
    
    public void loadAcceptedCharacters() {
        acceptedChars.put('A', "AZPMN") ;
    }
    
    public boolean isValidKeyword(String word, String expected)
    {
        if (word == null || word.matches("\\s*"))
            return false ;
    
        if (word.length() != expected.length())
            return false ;
    
        for(int idx = 0; idx < word.length(); idx++)
        {
            if (!isValidDigit(word.chatAt(idx), expected.charAt(idx)))
                return false ;
        }
    
        return true ;
    }
    
    public boolean isValidDigit(char chr, char expected) {
        String accepted ;
        if (chr != expected)
        {
            accepted = acceptedChars.get(chr) ;
            if (accepted == null)
                return false ;
            if (accepted.indexOf(chr) < 0) 
                return false ;
        }
        return true ;
    }