如何使用数组的一部分

3

抱歉,如果今天我发了很多愚蠢的问题时让大家见笑了(这只是一个前言)。然而,这是暑期课程的最后一项任务,我的老师已经不再关心/解释如何做我的第一堂编程课。

为了完成这个项目,我需要从.dat文件中打印一个整数列表到程序中,并以相反的顺序列出最多40个数组(我已经完成了所有这些)。我遇到的问题是他说程序应该足够灵活,以处理少于40个值。但是,根据我的目前的代码,我总是遇到一个错误,显示“nosuchelementexception”。任何帮助将不胜感激。下面是我目前的代码:

import java.io.*;               //Imports any file operation (ie Reading or Writing)
import java.util.Scanner;       //Imports scanner class

public class program3
{
    public static void main(String [] ars) throws IOException
    {
        double [] Values;               // creating array called value
        Values = new double [40];       // establishing array with 40 cells
        int k;                  // creating counter integer

        Scanner InputFile = new Scanner( new FileReader("temp.dat"));       // input file you wish to open.

        for (k = 0 ; k < Values.length ; k++)

            Values[k] = InputFile.nextDouble();


        for (k = Values.length - 1 ; k >= 0 ; k--)

            System.out.println("Cell " + k + " contains the value " + Values[k]);

        InputFile.close();
    }

}

1
无论文件中有多少元素,“Values.length”始终为“40”。如果有35个元素,尝试读取第36个元素将会出现问题。 - Pointy
1
Java 的惯例是不要将变量的第一个字母大写,第一个字符的大写是为了对象和类。请注意 stackoverflow 如何突出显示您的变量名。 - Zach
感谢您的建议,我会尽力不再继续这样做。 - Matthew Osman
8个回答

3
你遇到的问题是数组的length属性指的是声明的长度,而不是其中数据的数量。
当你试图使用长度(在这种情况下为40)来控制读取数据的循环时,如果要读取的元素较少,则会出现错误。
你想做的是只有在存在更多输入可获取时才读取更多的输入。
    int k = 0;
    while (inputFile.hasNextDouble()) {
        Values[k++] = inputFile.nextDouble();
    }

另外,考虑使用ArrayList代替数组。 ArrayList类允许您存储动态数量的数据,因此您不必担心预先分配存储空间:

    ArrayList<Double> values = new ArrayList<>();
    while (inputFile.hasNextDouble()) {
        values.add(inputFile.nextDouble());
    }

println() 循环还需要考虑实际读取的双精度数的数量。 - Tim
现有的打印循环只需要基于 values.size() 循环,而不是外部计数器。 - azurefrog
1
这个数组大小为40,但是你从1号索引开始存储。如果你实际读取了40个数字,会怎么样? - gkrls
非常感谢你,以及所有回答的人。我使用了这个方法,并在第二个listen for语句中添加了一个if语句: if (value[k] == 0) System.out.println(""); 这样一来,由于导入的.dat文件中缺少值,就可以消除任何原始的println输出为0的情况了。 - Matthew Osman
@xgeorgekx k++ 是一个后增运算符,因此数组的索引将从 0 开始。请参见 http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op1.html - azurefrog

1
您可以使用一个`while`循环和一个计数器。
import java.io.*;               // Imports any file operation (ie Reading or Writing)
import java.util.Scanner;       // Imports scanner class

public class program3
{
    public static void main(String [] ars) throws IOException
    {
        double [] Values;               // creating array called Values
        Values = new double [40];       // establishing array has 40 cells
        int counter = 0;                  // creating counter integer

        Scanner inputFile = new Scanner( new FileReader("temp.dat"));       //input file you with to open.

        while(inputFile.hasNextDouble()){

            Values[counter] = InputFile.nextDouble();
            counter++;

        }
        for (i = counter - 1 ; i >= 0 ; i--)

            System.out.println("Cell " + i + " contains the value " + Values[i]);

        InputFile.close();
    }

}

0
如果您不必使用数组,请使用ArrayList<Double>。这样可以调用values.add(value)来添加到列表中。长度是可变的,您可以使用相同的代码(只需将values[i]替换为values.get(i))。
但是,如果您必须使用数组,请创建一个向数组添加元素的方法。从0长度数组开始,当添加元素时,创建一个长度+1的新数组,然后将旧元素复制进去,并在末尾添加新元素。
还有许多其他方法可以解决这个问题,但这两种方法允许您使用现有的工作代码。
数组方法:
values = new double[0];

public void add(double x){
    double[] temp = new double[values.length +1];
    for(int i =0; i< values.lenght; i++){
        temp[i] = values[i];
    }
    temp[temp.length-1] = x;
    values = temp;
}

这只是基础中的基础。我们刚刚讲解了数组,还没有探索过类似于ArrayLists的东西。所以很遗憾我不能做到 >.< 谢谢你的理解。 - Matthew Osman
添加了使用数组的说明。 - Adam Yost
1
这里缺少的环节是代码需要知道何时停止从文件中读取值。如果解决了这个问题,数组也可以使用。 - Pointy
while(values.length<=40){ ... } - Adam Yost
你的 println() 循环还需要知道从文件中读取了多少个 double,以便知道从哪里开始向后工作。 - Tim
显示剩余2条评论

0
你的.dat文件中有40个元素吗?如果没有,你的代码可能会抛出异常。
for (k = 0 ; k < Values.length ; k++)
Values[k] = InputFile.nextDouble();

如果您的.dat文件不包含40个元素,则无法填充value[39]。

0

数组在初始化后具有固定大小,因此您可能希望使用动态数据结构,或者像下面发布的一样使用while循环。在这种情况下,我个人建议使用ArrayList

您还应该使用以下方法

Scanner.hasNext() 或者在您的特定情况下 Scanner.hasNextDouble() Docs

来获取任何新元素。

因此,您的程序将如下所示:

import java.io.*;               //Imports any file operation (ie Reading or Writing)
import java.util.Scanner;       //Imports scanner class
import java.util.ArrayList;

public class program3
{
    public static void main(String [] ars) throws IOException
    {
        ArrayList<Double> doubles = new ArrayList<Double>();

        Scanner inputFile = new Scanner( new FileReader("temp.dat"));

        while (inputFile.hasNextDouble()) {
               doubles.add(inputFile.nextDouble());
        }

        inputFile.close();


        for (Double value : doubles) {
             System.out.println(value);
        }
    }

}

Java的Collections类中有方便的方法可以进行排序。如果你还没有了解过,你可能想要去看一下。

0

我很欣赏你在Stack Overflow上的毅力。

为了奖励你,这里是你的答案。

你的第一个for循环遍历了你的新的空数组。这本来没问题,但你正在从Scanner对象InputFile中检索信息。

所以你实际上应该遍历那个对象!而不是你的数组。没有关系,这是一个经典错误。

这是我修改后的代码:

import java.io.FileReader;
import java.io.IOException; //Imports any file operation (ie Reading or Writing)
import java.util.Scanner; //Imports scanner class

public class program3
{
    public static void main( String [] ars ) throws IOException
    {
        double [] Values; // creating array called value
        Values = new double [40]; // establishing array has 20 cells
        int k; // creating counter integer

        //input file you with to open.
        Scanner InputFile = new Scanner( new FileReader( "temp.dat" ) ); 

        for ( k = 0; InputFile.hasNextDouble(); k ++ )

            Values[k] = InputFile.nextDouble();


        for ( k = Values.length - 1; k >= 0; k-- )

            System.out.println( "Cell " + k + " contains the value " + Values[k] );

        InputFile.close();
    }
}

希望这有帮助!


即使数组包含较少的元素,您仍然可以从索引39打印。 - gkrls
啊。我没有意识到那不是要求。我以为最多40个单元格的存在会很明显。在迭代中,数值0实际上是打印出来的。 - aaiezza

0

你应该使用ArrayList,这样就不需要最初设置数组的大小。这将使得数组中永远不会有空元素。

另一个选择是用占位符值(如-1)初始化数组,然后只有在值不为-1时才执行switch操作。


0
添加一个计数器来跟踪你放入数组中的项目数量,并使用它来确定在打印它们时何时停止。

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