在Java中打印数组变量时获取随机词汇

3

我正在学习Java的基础知识,但有一点观察不太明白。

以下代码应该打印一个base10数的二进制表示。虽然没有错误或警告,但是我仍在寻找答案以解决逻辑上的异常。

import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.*;

public class Main
{
    private static final Scanner scanner = new Scanner(System.in);

    public static void main(String args[]) {
        int n = scanner.nextInt();
        scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");

        int remainder, quotient, i=0;
        int[] binary=new int[n];

        /* Binary division -Extracting the 1's and 0's out of the base10 number and storing it in binary[] */
        while(n!=0){
            remainder=n%2;
            quotient=n/2;
            binary[i]=remainder;
            n=quotient;
            i++;
        }

        int k=i; // For storing the length of array till I want my bits to be reversed since all other bits are initialized to 0.

        /*Reversing the binary[] to get the coreect binary value.*/
        for(int j=0; j<=i; j++){
            int temp=binary[j];
            binary[j]=binary[i];
            binary[i]=temp;
            i--;
        }

        /*Printing out all the bits of binary number. */
        for(int l=1;l<=k;l++){
            System.out.print(binary[l]);
        }

        System.out.println(binary); /*Prints a garbage looking value: For ex- for 25 i get: [I@33909752 */
        scanner.close();
    }
}

我的代码存在的问题:

1. 当我尝试打印数组变量 - binary 时,出现了一些看起来像垃圾的随机文字。我无法理解可能的原因是什么。这种情况是否正常?如果是,它代表什么意思?

例如:

在我的代码中,当我输入 25 时,打印 binary 变量时会得到 [I@33909752 ,而不是我期望的像 [1,1,0,0,1,0,....,0] 这样的结果。

2. 如果我从 0 而不是 1 开始循环打印 binary 值,我会得到多一个前置的 0

例如:

for(int l=1;l<=k;l++)
{
  System.out.print(binary[l]);
}

当我将循环从25开始时,输出11001,但如果我从0开始循环,输出则为011001。我在代码中的其他地方添加了SOPLn语句并检查了数组的所有位置,但没有地方会导致数组的0索引变成0。我想知道为什么?

1个回答

5
  1. 不要导入任意的东西进入你的思维。你不需要使用 java.iojava.mathjava.securityjava.textjava.util.concurrent 或者 java.util.regex 包中的任何东西。到目前为止,你代码中唯一需要导入的是 java.util.Scanner

  2. 你不需要类似于 scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?") 的结构。如果你将要读取另一个标记(在你的代码中并没有发生),扫描器默认会跳过空格,包括换行符。还有一个方法 scanner.nextLine(),但是在这里你不需要它。

  3. 不要关闭 System.in。虽然围绕自己分配的资源创建的 Scanner 应该被关闭,但你不需要关闭 System.in

  4. System.out.println(Object) 打印调用对象的 toString() 方法的结果。对于不提供实现的类,比如数组,java.lang.Object 继承的方法 会产生 getClass().getName() + "@" + Integer.toHexString(hashCode())int[] 数组的类名是 [I,这就是为什么你会看到 [I@ 加上一些十六进制数字。

    使用 System.out.println(Arrays.toString(binary)); 代替。但是这将打印整个数组,包括未使用的元素。

  5. 不要在循环中修改现有变量,从而需要在外部作用域中创建新变量。相反,在循环中引入一个新的可变临时变量。此外,你必须熟悉标准的循环习惯用法,从索引零开始并排除结束索引(使用 < 而不是 <=)。

    当条件求值为 false 时,循环变量将包含被排除的结束索引。这个逻辑也适用于你的第一个 while 循环;之后,i 将包含第一个未使用的索引或已使用长度,这两种解释都是有效的。后续的使用必须排除它,使用 <,这是常见的模式。对于你的反转循环,这也意味着结束索引在使用之前必须递减。

    修复循环逻辑将修复你的前导零问题。

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    private static final Scanner scanner = new Scanner(System.in);

    public static void main(String args[]) {
        int n = scanner.nextInt();
        int remainder, quotient, i=0;
        int[] binary=new int[n];
        /* Binary division -Extracting the 1's and 0's
           out of the base10 number and storing it in binary[] */
        while(n!=0) {
            remainder=n%2;
            quotient=n/2;
            binary[i]=remainder;
            n=quotient;
            i++;
        }
        /*Reversing the binary[] to get the correct binary value.*/
        for(int j=0, k=i-1; j<k; j++,k--) {
            int temp=binary[j];
            binary[j]=binary[k];
            binary[k]=temp;
        }
        /*Printing out all the bits of binary number. */
        for(int l=0; l<i; l++) {
            System.out.print(binary[l]);
        }
        System.out.println();

        System.out.println(Arrays.toString(binary));
    }
}

25
11001
[1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

多么出色的答案。直截了当,正是我所需要的。顺便问一下,您能否评论一下我可以使数组大小动态化的方法?我的意思是,我的数组中有很多未使用的位,我想知道是否可以通过要求java将数组的大小保持在所需的大小来摆脱它们。我有Python背景,其中程序员有自由指示lists为可接受的大小,因此我想知道我们是否可以在Java中做类似的事情? - mishsx
2
Java的数组大小始终是固定的,因此您可以选择将其更改为使用List(例如java.util.ArrayList),或者只需用正确长度的新数组替换原数组,即在while循环后使用binary = Arrays.copyOf(binary, i);。或者您可以使用32 - Integer.numberOfLeadingZeros(n)来预测正确的数组大小。 - Holger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接