查找从输入文件WITHOUT数组中获取的数字模式

时间:2017-05-31 00:55:15

标签: java

首先,我有一个包含11行(或更少)数字的输入文件。

我的部分工作是找到模式(出现次数最多的数字)而不使用数组。在找到输入文件中的行数后,我尝试使用for循环或if循环。我知道在没有数组的情况下执行此操作听起来很愚蠢,但我不允许在此分配中使用数组。

由于我为输入文件中提取的每个数字创建了变量(earnGrade1,earnGrade2,earnGrade3等),我不确定如何在不使用连续if语句的情况下比较数字(如下例所示)

//Assume count has been declared and initialized to 0
//Assume earnedGrade1/2/3 has been intialized with the numbers 
pulled from input file

if(earnedGrade1 == earnedGrade2)
{
    count++;
}
if(earnedGrade1 == earnedGrade3)
{
    count++;
}

上面的例子似乎不是一个很好的查找模式的方法,因为我必须为每个和每个wonGrade变量做11个if语句。

如果有人有任何建议,请提供帮助。

感谢您的帮助,请理解我是编程新手。

4 个答案:

答案 0 :(得分:1)

没有数组的一种方法是编写一个辅助方法,如下所示:

static int count(double gradeToCount, double grade1, ..., double gradeN) {
    int count = 0;
    if (gradeToCount == grade1)
        count++;
    if (gradeToCount == grade2)
        count++;
    // And so on...
    return count;
}

就像你使用循环一样:

for (double grade : gradesArray)
    if (gradeToCount == grade)
        count++;

除了循环展开,你检查每个等级并自己递增计数。

一旦你可以计算每个年级的出现次数,那么你必须编写另一个展开的循环,在那里找到具有最大数量的等级。

编写辅助方法意味着您只需要手动写出2N比较而不是N 2 比较。

我真的不知道你应该从这个方面学到什么,除了为什么阵列是必要的我猜。

我再次考虑它,另一种方法是使用Scanner重复读取文件。像这样:

Scanner in1 = new Scanner(fileOrPath);
while (in1.hasNextDouble()) {
    double gradeToCount = in1.nextDouble();

    Scanner in2 = new Scanner(fileOrPath);
    while (in2.hasNextDouble()) {
        double grade = in2.nextDouble();
        if (grade == gradeToCount)
            count++;
    }
}

这也非常糟糕,但我想,这可能比手工编写比较更好。我认为Poosh的答案暗示了类似的东西。

答案 1 :(得分:0)

可能不是最有效的,但是这里是你提到的迄今为止你所提到的一个想法:将输入文件读入一个字符串。然后编写一些方法,让你可以对String做一些你可以用数组做的事情,比如获取项目的数量,并获得某个索引的项目。然后你可以使用这些方法做一些循环。

一种方法可能是获取String中的第一个数字,计算找到它的次数,然后存储该数字以及它在变量中的String中出现的次数。然后转到String中的第二个数字,执行相同的操作,如果数字显示的次数超过前一个数字,则重置这些变量。否则单独留下变量。一旦你到达字符串中的最后一项,你将拥有你的模式。

除了低效率之外的另一个缺点是,这只能找到单一模式。您可以通过使用另一个String来“使用方法”扮​​演数组角色来克服这个问题。

答案 2 :(得分:0)

我认为这里最简单(但最费力)的解决方案是使用你建议的几个if-else语句。我认为你的导师想告诉你在编程中使用几个if-else语句是低效的,并且他正在使用这个问题来转换到另一个概念。要么就是这样,要么教师只是通过引入这个要求让你的作业忙于工作。

由于你是一个入门课程,你可能还没有被教过更高级的数据结构,如ArrayList s,除非你被允许使用这样的结构进行这项任务,你将没有别的选择,但是在你的代码中创建一个巨大的if-else部分。

答案 3 :(得分:0)

我有一个想法,我知道这很痛苦,因为程序需要多次遍历文件,但是,它可能会有所帮助,因为它不使用任何数组也不使用Collection(注释中的说明< / em>的):

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

/**
 * The "mode" is the value that occurs most often
 */
public class ModeWithoutArray {

    public static void main(String[] args) {
        int count =0, lines = 0;
        double mode =0;
        File file = new File("C:\\Users\\Yahya\\Desktop\\grades.txt"); // for example
        try {
            Scanner read = new Scanner(file);
            // count how many lines/grades the file contains
            while(read.hasNextLine()){
                read.nextLine();
                lines++;
            }

            // now compare every grade with the others (line by line) specified by the index "i"
            for(int i=0; i<lines; i++){
                int result = count(i, file); // count how many time it's repeated
                if(result>count){ // if it's bigger than the current count
                    count=result; // accept it
                    mode = findGrade(file, i); //then find the actual grade at that line                
                }
            }
            read.close();


        } catch (FileNotFoundException e) {
            System.out.println("File Not Found");
            System.exit(0);
        }
        if(count>1){
           System.out.println("The Mode is: " + mode + ", Repeated " + count + " times" );
        }
        else{
            System.out.println("No Mode Found" );
        }
    }

        // this method to count the repetition of a grade at particular line
        private static int count(int atLine, File file){

            double gardeToCount = 0;
            int count=0;

            try {
                Scanner read = new Scanner(file);
                // find the grade at that line
                gardeToCount = findGrade(file, atLine);

                // then compare it with other grades
                while(read.hasNextLine()){
                    if(gardeToCount==Double.parseDouble(read.nextLine())){
                        count++;
                    }           
                }

                read.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            return count; // return the count
        }

        // this method to find the actual grade at a given line in the file
        private static double findGrade(File file, int atLine){
            int line =0;
            try {
                 Scanner read = new Scanner(file);
                 while(read.hasNextLine()){
                    if(line==atLine){
                        return Double.parseDouble(read.nextLine());
                    }
                    read.nextLine();
                    line++;
                }
                 read.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            return 0;
        }   
}

<强>测试

文件内容(grades.txt)

50
60
70
80
50
60
60
90
100

输出

The Mode is: 60.0, Repeated 3 times

<强>更新

另一种方法也更有效,而不是多次读取文件 [还添加了对文件内容的验证] ,你可以做这样的事情( 评论中的说明):

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

/**
 * The "mode" is the value that occurs most often
 */
public class ModeWithoutArray {
    static int count =0, lines = 0;
    static double mode =0;

    public static void main(String[] args) {

        // the file that contains the grades (a grade at each line)
        File file = new File("C:\\Users\\Yahya\\Desktop\\grades.txt");

        // get all grades and convert them to a String separated by one space
        String allGrades = collectGrades(file); 

        double gradeToComapre = 0;
        int gradeRep = 0;

        // compare every grade with the others and count its repetition
        // every round change mode and count to the bigger values
        for(int i=1; i<=lines; i++){
            gradeToComapre = grade(allGrades, i);
            for(int j=i; j<=lines; j++){
                if(gradeToComapre==grade(allGrades, j)){
                    gradeRep++;
                }
            }
            if(gradeRep>count){
                count=gradeRep;
                mode = gradeToComapre;
            }
            gradeRep = 0;
        }


        if(count>1){ // if there is a mode
           System.out.println("The Mode is: " + mode + ", Repeated " + count + " times." );
        }
        else{
            System.out.println("The Collection Has No Mode!" );
        }

    }



        //////////////////////////////////////////////////////////////////////


        /**
         * This method to collect all Valid Grades 
         * from a given file and concatenate them to a String to be
         * returned at the end
         * @param file
         */
        private static String collectGrades(File file){
            String allGrades = "";
            try {
                Scanner read = new Scanner(file);
                // read the file and accept ONLY valid grades 
                while(read.hasNextLine()){
                    String oneGrade = read.nextLine().trim();
                    if(!oneGrade.isEmpty() && isValidGrade(oneGrade)){
                        allGrades += oneGrade + " "; // one space between every grade
                        // increment the global variable lines 
                        // to be used in the comparison loops
                        lines++; 
                    }
                }
                read.close();
            } catch (FileNotFoundException e) {
                 System.out.println("File Does Not Exists!");
                 System.exit(0);
            }

            return allGrades;   
        }


        //////////////////////////////////////////////////////////////////////


        /**
         * This method to check if a given Grade is valid
         * this will return true/false
         * @param oneGrade
         */
        private static boolean isValidGrade(String oneGrade){
            try{ // try to parse it as a double value
                // this will throw an exception if it's not a number!
                double theGrade = Double.parseDouble(oneGrade);
                if(theGrade>=0 && theGrade<=100){ // is it in the range?
                    return true;
                }
            }catch(NumberFormatException e){
                // catch the exception if it's not a number
                // and return false
                return false;
            }
            // return false if it's <0 or >100
            return false;
        }



        //////////////////////////////////////////////////////////////////////


        /**
         * This method to fetch a particular grade from the
         * String that contains all grades
         * @param allGrades
         * @param index
         */
        private static double grade(String allGrades, int index){
            String oneGrade = "";
            int count = 0;
            for(char c : allGrades.toCharArray()){
                if(!Character.isWhitespace(c)){
                    // if it's not a space, concatenate the char to oneGrade
                    oneGrade += c;
                }
                else{ // the space determines the end of grade
                    count++;
                    if(count==index){ // if it's the required grade
                        // return it as a double
                        return Double.parseDouble(oneGrade);
                    }
                    else{// if it's not the required grade
                        // restart concatenation
                        oneGrade = "";
                    }
                }
            }
            // this will never be the case unless you 
            // ask for a grade out the range 
            // (e.g. there are 3 grades and you want the fourth!!)
            return -1;
        }

}

<强>测试

文件内容(grades.txt)

50
60.5
66
75
32
95
50.5
75
60.5
80
60.5
78

输出:

The Mode is: 60.5, Repeated 3 times.