【问题标题】:The bigger value in a matrix row矩阵行中的较大值
【发布时间】:2010-04-21 19:26:03
【问题描述】:

如何获得矩阵行的 2 个较大的数字?

如果矩阵在其他行有更大的数字,则无法显示。

例如,假设我有以下矩阵

int mat[][] ={{1,2,3}{4,5,6}{7,8,9}};

如果我从第 0 行搜索 2 个更大的数字,它应该返回索引 1 和 2(值 2 和 3)。

【问题讨论】:

  • 你的意思是它应该返回 1 & 2,还是应该返回 2 & 3?
  • 也许他想到了 index 1 和 2(在本例中等于值 2 和 3)
  • 谢谢,@Andreas;也许这就是解释。
  • 对不起。我的意思是索引 1 和 2。索引对我来说真的很重要

标签: java math matrix


【解决方案1】:

由于您的“矩阵”作为数组数组存储在 Java 中的方式,问题被简化为只需在 int[] 中查找最高 2 个元素(可能具有相等值)的索引。

因此解决方案非常简单:

public class Max2 { 
    static int[] max2(int... nums) {
        int high1v = Integer.MIN_VALUE;
        int high2v = Integer.MIN_VALUE;
        int high1i = -1;
        int high2i = -1;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] >= high1v) {
                high2v = high1v;
                high2i = high1i;
                high1v = nums[i];
                high1i = i;
            } else if (nums[i] >= high2v) {
                high2v = nums[i];
                high2i = i;
            }
        }
        return new int[] { high1i, high2i };
    }
}

这使用阵列的 1-pass O(N) 线性扫描。 Integer.MIN_VALUE&gt;= 比较的组合使其工作得很好。 high1i 是第一个最高元素的索引,high2v 是第二个最高元素的值,以此类推

static void print(int[] arr) {
    System.out.println(java.util.Arrays.toString(arr));
}
public static void main(String[] args) {
    int[][] matrix = {
        { 1,2,3 }, // [2, 1]
        { 6,5,4 }, // [0, 1]
        { 8,7,9 }, // [2, 0]
        { 0,0,0 }, // [2, 1]
    };

    // print the indices of the maximum 2 elements in each row
    for (int[] row : matrix) {
        print(max2(row));
    }

    print(max2(matrix[1]));
    // matrix[1] is the { 6, 5, 4 } row; prints "[0, 1]"

    print(max2(Integer.MIN_VALUE, Integer.MIN_VALUE));
    // works with varargs, and Integer.MIN_VALUE as real values
}

【讨论】:

  • +1 用于 O(n) 算法而不是 O(n log(n)) 排序方法。
【解决方案2】:

更新以返回索引。另外,我想在此过程中更改原始矩阵是不可取的,所以我编写了一个测试来确认我的原始实现 确实 更改了矩阵,然后修改了代码使其不再.

package playground.tests;

import java.util.Arrays;

import junit.framework.TestCase;

public class BiggerTest extends TestCase {

    public void testBigger() throws Exception {
        int mat[][] = { { 3, 1, 2 }, { 4, 5, 6 }, { 7, 8, 9 } };
        int[] result = bigger(0, 2, mat);
        assertEqualArrays(new int[] { 2, 3 }, result);
    }

    public void testBiggerDoesntChangeOriginalMatrix() throws Exception {
        int mat[][] = { { 3, 1, 2 }, { 4, 5, 6 }, { 7, 8, 9 } };
        bigger(0, 2, mat);
        assertEqualArrays(new int[] { 3, 1, 2 }, mat[0]);
    }

    public void testBiggerIndex() throws Exception {
        int mat[][] = { { 3, 1, 2 }, { 4, 5, 6 }, { 7, 8, 9 } };
        int[] result = biggerIndexes(0, 2, mat);
        assertEqualArrays(new int[] { 2, 0 }, result);
    }

    private int[] biggerIndexes(int rowIndex, int count, int[][] matrix) {
        int[] biggerValues = bigger(rowIndex, count, matrix);
        int[] row = matrix[rowIndex];
        int[] result = new int[count];
        for (int i = 0; i < result.length; i++) 
            result[i] = findIndex(biggerValues[i], row);
        return result;
    }

    private int findIndex(int value, int[] values) {
        for (int i = 0; i < values.length; i++) 
            if (values[i] == value)
                return i;
        return -1;
    }

    private int[] bigger(int rowIndex, int count, int[][] matrix) {
        int[] row = copy(matrix[rowIndex]);
        Arrays.sort(row);
        int[] result = new int[count];
        for (int i = 0; i < count; i++)
            result[i] = row[i + row.length - count];
        return result;
    }

    private static int[] copy(int[] original) {
        int[] result = new int[original.length];
        for (int i = 0; i < result.length; i++) 
            result[i] = original[i];
        return result;
    }

    private static void assertEqualArrays(int[] a, int[] b) {
        assertEquals(a.length, b.length);
        for (int i = 0; i < a.length; i++)
            assertEquals(a[i], b[i]);
    }
}

【讨论】:

  • 嘿@carl 我猜他正在寻找更大值的索引。
  • 嗨@Carl。您的解决方案不考虑较大值的索引,不是吗?我怎样才能获得较大值的索引?
  • @marionmaiden,我已更新代码以返回索引;往上看。另外,我最初的实现是搞乱了矩阵,我想你不希望这样。
  • 嗨,Carl,我会按照您最初的要求给您正确的答案,但是您不认为代码可以更小,因为我已经调整了您的第一个解决方案吗?我认为它在没有那么多行的情况下做同样的事情(我没有考虑你为测试而创建的断言方法)。
  • @marionmaiden,当然,它可以更小;大多数代码总是可以更小。我认为,简洁本身并不是一个伟大的美德——我总是寻求清晰。简洁通常有助于清晰,但并非总是如此——当我必须在它们之间做出选择时,我会选择清晰。我认为这段代码至少是相当清晰的。而且,由于测试,正确。正确性是另一个不错的品质。 :-)
【解决方案3】:

我对@Carl 代码进行了改编,得到了这个

private int[] bigger(int rowIndex, int count, int[][] matrix) {
    int[] row = matrix[rowIndex];
    int[] original = matrix[rowIndex];
    int[] result = new int[count];

    Arrays.sort(row);

    for (int i = 0; i < count; i++){
        for(int j = 0; j < original.length; j++){
            if(row[row.length - 1 - i] == original[j]){
                result[i] = j;
                original[j] = Integer.MIN_VALUE;
                // break;
            }
        }
    }
    return result;
}

我们可以在我评论的地方放一个break指令,但我不知道它是否会提高算法的性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多