Java:确定2D数组是否具有不连续的值

时间:2017-01-26 05:15:50

标签: java arrays multidimensional-array

我有一个问题。我在Java中有一个2D数组,如果数组有不连续的值,我想检查数组。

示例:

True:
1 2 3 3
1 4 4 5
2 6 6 5
7 7 8 8

上面的数组应该返回true,因为数字2出现在2个不连续的区域(第1行第2行和第3行第1列)。

False:
1 2 3 3
1 4 4 5
6 7 7 5
8 8 9 9

上面的数组应该返回false,因为没有值出现在2个或更多不连续的区域中。

3 个答案:

答案 0 :(得分:1)

检查以下代码。评论解释了正在发生的事情。 它包含三个类:ArraysMainIndexIndexList,它们扩展了ArrayList

<强>已更新

基本上,获取所有不同的值并将它们存储在地图中。对于每个值(如果它出现多次)将具有多个索引(数组中值的位置)。

遍历数组逐个添加每个值的索引。如果遇到一个索引,其rowIndex与所有其他索引的rowIndex不匹配,而对于当前值的columnIndex则相同,那么该值是不合适的。

public class ArraysMain {

private static final int[][] values = {{1, 2, 3, 3}, {1, 4, 4, 5}, {2, 6, 6, 5}, {7, 7, 8, 8}};
// private static final int[][] values = {{1, 2, 3, 3}, {1, 4, 4, 5}, {6, 7, 7, 5}, {8, 8, 9, 9}};

public static void main(String[] args) {
    System.out.println("Has Discontigous: " + hasDiscontigous());
}

public static boolean hasDiscontigous() {
    // Initialize a map to hold the indexes for each int found
    // For example the value 3 will be mapped to the indexes as shown below
    // (3) -> [0,2], [0,3]
    // (4) -> [1,1], [1,2]
    Map<Integer, IndexList<Index>> map = new HashMap<>();

    // Iterate through the int array and add the indexes per the value
    for (int i = 0; i < values.length; i++) {
        // Get the i-th row
        int[] row = values[i];

        // Iterate through the current row values and add them to the map with the corresponding indexes
        for (int j = 0; j < row.length; j++) {
            // If the map does not contain the j-th value then that value has not been added yet so 
            // Initialize the List
            if (!map.containsKey(row[j])) {
                // Initialize the list
                map.put(row[j], new IndexList<>());
            }

            // Get the value's indexes list and add this value's index
            // If the value is added to the list, 'true' is returned
            boolean add = map.get(row[j]).add(new Index(i, j));

            if (!add) {
                // If false means a discontiguous value has been found
                System.out.println("Value: " + values[i][j] + " is discontigous");
                return true;
            }
        }
    }

    return false;
}

/**
 * This will hold the indexes i.e rowIndex and columnIndex
 */
public static class Index {

    private int rowIndex;
    private int columnIndex;

    public Index(int rowIndex, int columnIndex) {
        this.rowIndex = rowIndex;
        this.columnIndex = columnIndex;
    }

    public int getRowIndex() {
        return rowIndex;
    }

    public void setRowIndex(int rowIndex) {
        this.rowIndex = rowIndex;
    }

    public int getColumnIndex() {
        return columnIndex;
    }

    public void setColumnIndex(int columnIndex) {
        this.columnIndex = columnIndex;
    }

}

/**
 * Extend the {@code ArrayList} object and override the add() method
 * @param <T> 
 */
public static class IndexList<T> extends ArrayList<Index> {

    /**
     * This method determines if a discontigous value has been found. If a value is not discontigous it's indexes are added to the list, 
     * if not, this method returns false
     * @param e
     * @return 
     */
    @Override
    public boolean add(Index e) {
        // Before adding an index object ensure the row or column do not match

        for (Index thi : this) {
            // Check if the rows match
            if (e.rowIndex != thi.rowIndex && e.columnIndex != thi.columnIndex) {
                // If the rowIndex and columnIndex do not match then don't add the value
                return false;
            }

        }

        return super.add(e); //To change body of generated methods, choose Tools | Templates.
    }

}

}

答案 1 :(得分:0)

这是另一个solutoin。虽然需要优化,但比较容易理解。

更新:这只是检查每个值是否不连续,如果是,则为一个或多个。

public class CheckIfDiscontiguous {
public static void main(String args []){
    CheckIfDiscontiguous so = new CheckIfDiscontiguous();
    int[][] input = {{1,2,3,3}, {1,4,4,5}, {2,7,7,5}, {8,8,9,9}};
    System.out.println(so.discontiguousValueCheck(input));
}
public boolean discontiguousValueCheck(int[][] input){
    int m=4;
    int n=4;
    int flag = 0;
    int count = 1;
    int discontiguousCount = 1;
    int[] discontiguousSuspects = new int[16]; 
    int index = 0;
    for(int i=0; i<4; i++){
        for(int j=0; j<4; j++){

            //check for 1st row starts
            //check for (0,0)
            if(i==0 && j==0){    
                if(!(input[0][0]==input[0][1] || input[0][0]==input[1][0])){
                    discontiguousSuspects[index] = input[0][0];
                }
            }
            //check for (0,1)
            if(i==0 && j==1){
                if(!(input[0][1]==input[0][0] || input[0][1]==input[0][2] || input[0][1]==input[1][1])){
                    //System.out.println("goes");
                    discontiguousSuspects[index] = input[0][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[0][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (0,2)
            if(i==0 && j==2){
                if(!(input[0][2]==input[0][1] || input[0][2]==input[0][3] || input[0][2]==input[1][2])){
                    discontiguousSuspects[index] = input[0][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[0][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (0,3)
            if(i==0 && j==3){
                if(!(input[0][3]==input[0][2] || input[0][3]==input[1][3])){
                    discontiguousSuspects[index] = input[0][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[0][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for 1st row ends

            //check for 2nd row elements start
            //check for (1,0)
            if(i==1 && j==0){    
                if(!(input[1][0]==input[0][0] || input[1][0]==input[2][0] || input[1][0]==input[1][1])) {
                    discontiguousSuspects[index] = input[1][0];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][0]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (1,1)
            if(i==1 && j==1){
                if(!(input[1][1]==input[1][0] || input[1][1]==input[0][1] || input[1][1]==input[1][2] || input[1][1]==input[2][1])){
                    discontiguousSuspects[index] = input[1][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (1,2)
            if(i==1 && j==2){
                if(!(input[1][2]==input[1][1] || input[1][2]==input[0][2] || input[1][2]==input[1][3] || input[1][2]==input[2][2])){
                    discontiguousSuspects[index] = input[1][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (1,3)
            if(i==1 && j==3){
                if(!(input[1][3]==input[1][2] || input[1][3]==input[0][3] || input[1][3]==input[2][3])){
                    discontiguousSuspects[index] = input[1][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }

            //check for 2nd row elements end


            //check for 3rd row elements start
            //check for (2,0)
            if(i==2 && j==0){    
                if(!(input[2][0]==input[1][0] || input[2][0]==input[3][0] || input[2][0]==input[2][1])) {
                    count++;
                    discontiguousSuspects[index] = input[2][0];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][0]){
                                if(discontiguousCount==2){
                                return true;
                                }
                                discontiguousCount++;
                            }
                        }
                    }
                }
            }
            //check for (2,1)
            if(i==2 && j==1){
                if(!(input[2][1]==input[2][0] || input[2][1]==input[1][1] || input[2][1]==input[2][2] || input[2][1]==input[3][1])){
                    discontiguousSuspects[index] = input[2][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (2,2)
            if(i==2 && j==2){
                if(!(input[2][2]==input[2][1] || input[2][2]==input[1][2] || input[2][2]==input[2][3] || input[2][2]==input[3][2])){
                    discontiguousSuspects[index] = input[2][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (2,3)
            if(i==2 && j==3){
                if(!(input[2][3]==input[2][2] || input[2][3]==input[1][3] || input[2][3]==input[3][3])){
                    discontiguousSuspects[index] = input[1][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }

            //check for 3rd row elements end

            //check for 4th row starts
            //check for (3,0)
            if(i==3 && j==0){    
                if(!(input[3][0]==input[3][1] || input[3][0]==input[2][0])){
                    discontiguousSuspects[index] = input[3][0];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (3,1)
            if(i==3 && j==1){
                if(!(input[3][1]==input[3][0] || input[0][1]==input[3][2] || input[3][1]==input[2][1])){
                    discontiguousSuspects[index] = input[3][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[3][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (3,2)
            if(i==3 && j==2){
                if(!(input[3][2]==input[3][1] || input[3][2]==input[3][3] || input[3][2]==input[2][2])){
                    discontiguousSuspects[index] = input[3][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[3][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (3,3)
            if(i==0 && j==3){
                if(!(input[3][3]==input[3][2] || input[3][3]==input[2][3])){
                    discontiguousSuspects[index] = input[3][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[3][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for 3rd row ends

        }
    }
    return false;
}

}

答案 2 :(得分:0)

基本上,我们需要对每个数组值进行分组&#39;位置。一旦我们知道所有位置,我们需要找出它们是否都是相邻的(对于每个pos1,都有pos2与距离(pos1,pos2)&lt; 2)。

public class ContiguousArray {

    public static <E> boolean isContiguous(E[][] array) {
        Map<E, Collection<Integer[]>> groupedPositions = groupLocations(array);

        return groupedPositions.values().stream().allMatch(ContiguousArray::allContiguous);
    }

    private static <E> Map<E, Collection<Integer[]>> groupLocations(E[][] array) {
        Map<E, Collection<Integer[]>> locations = new HashMap<>();

        for(int x = 0; x < array.length; x++) {
            for(int y = 0; y < array[x].length; y++) {

                Collection<Integer[]> knownIndices;
                Integer[] currentPosition = new Integer[] { x, y };
                E currentElement = array[x][y];

                if(locations.containsKey(currentElement)) {
                    knownIndices = locations.get(currentElement);
                } else {
                    knownIndices = new HashSet<>();

                    locations.put(currentElement, knownIndices);
                }
                knownIndices.add(currentPosition);
            }
        }
        return locations;
    }

    /**
     * @return true, if all of the provided indices have an adjacent index in
     *         the same collection. Also true, if the collection's size < 2.
     *         False, otherwise.
     */
    private static boolean allContiguous(Collection<Integer[]> indices) {
        return indices.stream().allMatch(thisIndex -> hasAdjacent(indices, thisIndex) || indices.size() < 2);
    }

    private static boolean hasAdjacent(Collection<Integer[]> indices, Integer[] thisIndex) {
        return indices.stream().anyMatch(thatIndex -> isAdjacent(thisIndex, thatIndex));
    }

    private static boolean isAdjacent(Integer[] thisIndex, Integer[] thatIndex) {
        return thatIndex != thisIndex && calculateDistance(thisIndex, thatIndex) < 2;
    }

    private static int calculateDistance(Integer[] indexA, Integer[] indexB) {
        int sum = 0;

        for (int i = 0; i < indexA.length; i++) {
            sum += Math.abs(indexA[i] - indexB[i]);
        }
        return sum;
    }
}

与JUnit测试一起:

public class ContiguousArrayTest {
    @Test
    public void test() {
        assertFalse(ContiguousArray.isContiguous(new Integer[][] { 
            { 1, 2, 3, 3 }, 
            { 1, 4, 4, 5 }, 
            { 2, 6, 6, 5 }, 
            { 7, 7, 8, 8 } 
        }));

        assertFalse(ContiguousArray.isContiguous(new Character[][] { 
            { 'a', 'b' }, 
            { 'b', 'a' }, 
        }));

        assertTrue(ContiguousArray.isContiguous(new Character[][] { 
            { 'a', 'a', 'a' }, 
            { 'b', 'a' }, 
            { 'b' }, 
        }));

        assertTrue(ContiguousArray.isContiguous(new Integer[][] { 
            { 1, 2, 3, 3 }, 
            { 1, 4, 4, 5 }, 
            { 6, 7, 7, 5 }, 
            { 8, 8, 9, 9 } 
        }));

        assertTrue(ContiguousArray.isContiguous(new Integer[][] { 
            { 1, 2, 3, 3 }, 
            { 1, 1, 4, 5 }, 
            { 6, 1, 7, 5 }, 
            { 8, 8, 9, 9 } 
        }));

        assertTrue(ContiguousArray.isContiguous(new Integer[][] { 
            { 1, 2 }, 
            { 2, 2 }
        }));
    }
}