如何使用close()或reset()从头开始读取扫描仪

时间:2015-08-05 05:34:21

标签: java java.util.scanner

我有一个3x3矩阵输入流,我在这里计算两个主要对角线之和的绝对差值。示例如下:

  

11 2 4

     

4 5 6

     

10 8 -12

应该给我15的结果,因为:

| 11 + 5 - 12 | - | 4 + 5 + 10 |

= | 4 | - | 19 |

= 15

我的代码如下:

public class Solution {

static int diagSumL(int lines, Scanner in) {
    int currSum;
    currSum = 0;
    for (int i = 0; i < lines; i++) {
        for (int j = 0; j < i; j++) {
            in.nextInt();
        }
        currSum += in.nextInt();
        System.out.println(currSum);
        if (in.hasNextLine() == true) {
            in.nextLine();
        }
    }
    return currSum;
}

static int diagSumR(int lines, Scanner in) {
    int currSum, index;
    currSum = 0;
    for (int i = lines; i > 0; i--) {
        for (int j = 1; j < i; j--) {
            in.nextInt();
        }
        currSum += in.nextInt();
        System.out.println(currSum);
        if (in.hasNextLine() == true) {
            in.nextLine();
        };
    }
    return currSum;
}

static int absDiff(int a, int b) {
    return Math.abs(a) + Math.abs(b);
}

public static void main(String[] args) {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
    Scanner in = new Scanner(System.in);
    int lines, sumDiagL, sumDiagR;
    lines = in.nextInt();
    sumDiagL = diagSumL(lines, in);
    in.close();
    in = new Scanner(System.in);
    sumDiagR = diagSumR(lines, in);
    int result = absDiff(sumDiagL, sumDiagR);
    System.out.println(result);
}

}

我的代码错误在第3行到最后一行,它来自我的diagSumR方法试图调用in.intNext(),其中错误是:

  

线程中的异常&#34; main&#34; java.util.NoSuchElementException

我想要做的是重置扫描仪,以便我可以重新开始并从头开始重新读取扫描仪(这样我就可以计算出另一条对角线的总和)。我是否使用close()错误?(在线使用close()的每个例子都是这样的)

也可以使用Scanner类中的reset()作为替代方法,如果是这样的话?

2 个答案:

答案 0 :(得分:1)

1。为什么它不起作用。

这不起作用,因为当您使用close()关闭扫描仪时,它不仅会“关闭”对象,还会关闭基础System.in。因此,即使您创建新的Scanner实例,基础System.in也将被关闭,因此您将获得异常。在拨打System.in.available();之前和之后,可以使用close()检查此项。此外,它不可能在关闭后重新打开流。

请关注documentation

  

如果其底层可读也实现了Closeable接口,那么将调用可读的close方法

另一方面,

System.in会返回InputStream来实现Closeable, AutoCloseable

2。应该怎么做。

即使您不想将矩阵存储在内存中,您的解决方案也不是最理想的,因为它需要用户输入矩阵两次,因为从System.in读取某些内容后您无法重新读取它用Scanner!你拥有所有的数据,所以你可以实际计算两个总和,存储2个和变量,因为你无论如何都在阅读所有数字。请注意哪个数字被添加到哪个和变量。

3。怎么做。

由于你传递了Scanner个实例,我认为close()没有任何理由并在调用diagSumR之前重新初始化,只需在结束时关闭它方法。正如我所提到的那样,缺点是您需要再次手动输入矩阵。

答案 1 :(得分:0)

不确定,问题是否是要了解Scanner(你试图向后移动,之后也是如此)

如果没有,这可以更简单地解决(假设方形矩阵)

for (int i = 0; i < N; i++) {
    diagonal1 += A[i][i]; // 0,0 + 1,1 + 2,2 + ... + n,n
    diagonal2 += A[N-1-i][i]; // n,0 + n-1, 1, .. + 2,2 + 1, n-1 + 0,n
}

其中N是矩阵A的大小(&我希望很明显N-1的使用是指数从0到N-1)