我的txtfile阅读器prgram有错误

时间:2015-11-17 23:59:04

标签: java

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;


public class GradeAverage {

    private String filename;
    private List<String> invalidEntries;
    private List<Entry> validEntries;

    public GradeAverage() {
        invalidEntries = new ArrayList<>();
        validEntries = new ArrayList<>();
    }

    private static class Entry{
        private String name;
        private List<Integer> grades;
        public Entry() {
        grades = new ArrayList<>();

        public void add(int g){
            grades.add(g);
        }
        public void setName(String name){
            this.name = name;
        }
        public double getAverage(){

            if(grades.size() == 0)
                return 0.0;

            double avg = 0.0;
            for(Integer x: grades){
                avg += x;
            }
            avg /= grades.size();
            return avg;
        }

        public String toString(){
            return name + " " + getAverage() + "\n";
        }
    }

    public static void main(String[] args) {

        GradeAverage gradeApp = new GradeAverage();
        System.out.println("gradesheet.txt");
        gradeApp.setFilename("gradesheet.txt");

        gradeApp.readFile();
        gradeApp.process();

    }

    private void process() {
        Entry max = new Entry();
        Entry min = new Entry();
        for(Entry entry : validEntries){
            if(max.getAverage() < entry.getAverage())
            {
                max = entry;
            }
            if(min.getAverage() >= entry.getAverage())
            {

                System.out.println("READ");
                min = entry;
            }
        }
        System.out.print("MAX:\t"+max);
        System.out.print("MIN:\t"+min);
        System.out.println("\nExcluded Entries:");
        for(String str: invalidEntries){
            System.out.println(str);
        }
    }

    private void readFile() {
        Scanner in = null;
        try {
            in = new Scanner(new File(filename));
        } catch (FileNotFoundException e1) {
            System.exit(404);
        }
        while(in.hasNext()){
            String nextLine = in.nextLine();
            try{
                Entry entry = new Entry();
                StringTokenizer tokenizer = new StringTokenizer(nextLine);
                String name = tokenizer.nextToken();
                if(!valid(name))
                    throw new Exception();
                entry.setName(name);
                while(tokenizer.hasMoreTokens()){
                    entry.add(Integer.parseInt(tokenizer.nextToken()));
                }
                validEntries.add(entry);
    //              System.out.print("added\n"+entry);
            }
            catch(Exception e){
                invalidEntries.add(nextLine);
            }
        }
        in.close();
    }

    private boolean valid(String name) {
        for(int i = 0; i < name.length(); ++i){
            if(!Character.isLetter(name.charAt(i)))
                return false;
        }
        return true;
    }

    private void setFilename(String filename) {
        this.filename = filename;
    }

}

此代码用于获取成绩的最低和最高平均值。但是,当它试图显示最低等级时,结果将继续显示为零0.0。这是一个例子。

输入

  

I 30 12 43

     

64 46爱

     

code 22 2 2 113

     

somuch 13 99

输出

  

gradesheet.txt

     

MAX:somuch 56.0

     

MIN:null 0.0

     

排除的参赛作品:64 46爱

我做错了什么?我真的需要帮助...

2 个答案:

答案 0 :(得分:0)

问题在于:

Entry max = new Entry(); // defaultly constructed, so max.getAverage() == 0
Entry min = new Entry(); // defaultly constructed, so min.getAverage() == 0
for(Entry entry : validEntries){ // entry has only positive grades
    ....
    if(min.getAverage() >= entry.getAverage()) // 0 >= 'something, greater than 0' is always false.
}

使用simillar算法查找最小值/最大值,使用列表的第一个元素初始化默认值(Entry maxEntry min)时,这被认为是明智的。所以将之前的内容改为

Entry max = validEntries[0];
Entry min = validEntries[0];

答案 1 :(得分:0)

在您的代码中,只要没有负值,以下代码部分就会使min保持为0.0。见下面的评论:

        Entry max = new Entry();
        Entry min = new Entry();
        //min.getAverage() is 0.0 for the first ever time
        //max.getAverage() is 0.0 for the first ever time
        for(Entry entry : validEntries){
            if(max.getAverage() < entry.getAverage())
            {
                //0.0 is < entry.getAverage(), so max works file
                max = entry;
            }
            if(min.getAverage() >= entry.getAverage())
            {
                /* is 0.0 >= entry.getAverage(), no unless entry.getAverage is less than 0.0 hence, this condition is not executed until the entry.getAverage() is not a negative value */
                System.out.println("READ");
                min = entry;
            }
        }

我决定当for循环通过第一个条目时,我将设置min和max的平均条目允许说x(使用布尔标志)并且在后续循环中我比较先前存储的min和max中的值和I我保证永远得到正确的价值观。如果只有一个输入,则min和max都相同,如果有多个条目,则min和max分配正确的值。 见下文:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;


public class GradeAverage {

    private String filename;
    private List<String> invalidEntries;
    private List<Entry> validEntries;

    public GradeAverage() {
        invalidEntries = new ArrayList<>();
        validEntries = new ArrayList<>();
    }

    private static class Entry{
        private String name;
        private List<Integer> grades;
        public Entry() {
        grades = new ArrayList<>();
    }
    public void add(int g){
        grades.add(g);
    }
    public void setName(String name){
        this.name = name;
    }
    public double getAverage(){

        if(grades.size() == 0)
            return 0.0;

        double avg = 0.0;
        for(Integer x: grades){
            avg += x;
        }
        avg /= grades.size();
        return avg;
    }

    public String toString(){
        return name + " " + getAverage() + "\n";
    }
}

public static void main(String[] args) {

    GradeAverage gradeApp = new GradeAverage();
    System.out.println("gradesheet.txt");
    gradeApp.setFilename("gradesheet.txt");

    gradeApp.readFile();
    gradeApp.process();

}

private void process() {
    Entry max = new Entry();
    Entry min = new Entry();

    //first loop, assign both min and max entry
    boolean firstTime = true; 

    for(Entry entry : validEntries){
        //first time only
        if(firstTime) {
            max = entry; 
            min = entry; 
            firstTime = false; 
        } else {
            //now search for minimum and maximum
             if(max.getAverage() < entry.getAverage())
                {
                    max = entry;
                }
                if(min.getAverage() >= entry.getAverage())
                {

                    //System.out.println("READ MIN " + min.toString());
                    min = entry;
                }
        }

    }
    System.out.print("MAX:\t"+max);
    System.out.print("MIN:\t"+min);
    System.out.println("\nExcluded Entries:");
    for(String str: invalidEntries){
        System.out.println(str);
    }
}

private void readFile() {
    Scanner in = null;
    try {
        in = new Scanner(new File(filename));
    } catch (FileNotFoundException e1) {
        System.exit(404);
    }
    while(in.hasNext()){
        String nextLine = in.nextLine();
        try{
            Entry entry = new Entry();
            StringTokenizer tokenizer = new StringTokenizer(nextLine);
            String name = tokenizer.nextToken();
            if(!valid(name))
               throw new Exception();
            entry.setName(name);
            while(tokenizer.hasMoreTokens()){
                entry.add(Integer.parseInt(tokenizer.nextToken()));
            }
            validEntries.add(entry);
              System.out.print("added\n"+entry.toString());
        }
        catch(Exception e){
            invalidEntries.add(nextLine);
        }
    }
    in.close();
}

private boolean valid(String name) {
    for(int i = 0; i < name.length(); ++i){
        if(!Character.isLetter(name.charAt(i)))
            return false;
    }
    return true;
}

private void setFilename(String filename) {
    this.filename = filename;
}

}

我只修改了Process方法,请参阅下面boolean flag的用法和if条件:

private void process() {
    Entry max = new Entry();
    Entry min = new Entry();

    //first loop, assign both min and max entry
    boolean firstTime = true; 

    for(Entry entry : validEntries){
        //first time only
        if(firstTime) {
            max = entry; 
            min = entry; 
            firstTime = false; 
        } else {
            //now search for minimum and maximum
             if(max.getAverage() < entry.getAverage())
                {
                    max = entry;
                }
                if(min.getAverage() >= entry.getAverage())
                {

                    //System.out.println("READ MIN " + min.toString());
                    min = entry;
                }
        }

    }
    System.out.print("MAX:\t"+max);
    System.out.print("MIN:\t"+min);
    System.out.println("\nExcluded Entries:");
    for(String str: invalidEntries){
        System.out.println(str);
    }
}

针对以下输入运行后:

  

I 30 12 43

     

64 46爱

     

code 22 2 2 113

     

somuch 13 99

我得到以下输出:

  

MAX:somuch 56.0

     

MIN:I 28.333333333333332

     

排除的条目:

     

64 46爱

MAX无论如何都是正确的,MIN I 30 12 43