0

I'm trying to write a code that counts the number of lines and characters from a file, then sorts any character (including space and commas)

what I come up with.

import java.io.BufferedReader;


        File file1 = new File("C:/input.txt");
        BufferedReader in = new BufferedReader(new FileReader(file1));

        int nextChar;
        char ch;

        int[] count = new int[1000];





        in.close();
    }
}

Thanks in advance!

David
  • 37
  • 7
  • Edit the question to include the current output of the program so that we can help better understand the problem. If you can't do that then explain where the compiler error is occurring – Chris Gong Jul 23 '16 at 22:43

2 Answers2

1

Okay, so the tricky thing here is how does one go about sorting an array of primitive type int in descending order? Well, there are a bunch of posts on this site that talk about Arrays.sort(array, Collections.reverseOrder()); but this can only be used on arrays of objects, not primitive types like int. So the best way to go about this is to sort the array in ascending order using the built-in Arrays method and then traverse the entire array to reverse the elements in the array. So you should consider adding this snippet of code towards the end of your program,

Arrays.sort(count);//sort in ascending order
for(int i = 0; i < count.length; i++){ //reversing the order of the array
    int k = count[i]; //swapping the i-th element with the i-th to last element
    count[i] = count[count.length - 1 - i];
    count[count.length - 1 - i] = k;
}

Personally, I'd suggest putting the code above before this for loop,

for (i = 0; i < 26; i++) {

    System.out.printf("%c : %d", i + 'A', count[i]);

    System.out.println("");
}
Chris Gong
  • 8,031
  • 4
  • 30
  • 51
1

You could use a Map which you then sort using a self-written comparator (I stole the code from this thread), this way you don't have to pre-define what characters to count (as you would with arrays).

This would look something like this:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class CountCharsFromFile {
    static BufferedReader b;

    public static void main(String[] args) {

        try {
            FileReader fr = new FileReader("C:\\test.txt");
            b = new BufferedReader(fr);

            Map<String, Double> count = new HashMap<String,Double>();
            ValueComparator bvc = new ValueComparator(count);
            TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);

            int totalChars = 0;
            int totalWords = 0;

            String currentLine;

            while ((currentLine = b.readLine()) != null){
                for (int i = 0; i < currentLine.length(); i++) {

                    //Char count:
                    totalChars += 1;

                    //Adding all chars to the Map:
                    char currentChar = Character.toLowerCase(currentLine.charAt(i));

                    if (! count.containsKey(String.valueOf(currentChar))){
                        count.put(String.valueOf(currentChar), 1.0);
                    }else{
                        count.put(String.valueOf(currentChar), count.get(String.valueOf(currentChar)) + 1);
                    }

                }

                //Counting words:

                String[] currentLineSplit= currentLine.split("\\s+");

                for (String string : currentLineSplit) {
                    totalWords += 1;
                }

            }

            sorted_map.putAll(count);

            //Output:
            System.out.println("Words: " + totalWords);
            System.out.println("Chars: " + totalChars);
            System.out.println(sorted_map.toString());


        } catch (FileNotFoundException e) {
            System.err.println("Error, file not found!");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("Error reading file!");
            e.printStackTrace();
        }finally{
            try {
                b.close();
            } catch (IOException e) {
                System.err.println("Couldn't close the BufferedReader!");
                e.printStackTrace();
            }

        }

    }
}




//comparator class:

class ValueComparator implements Comparator<String> {
    Map<String, Double> base;

    public ValueComparator(Map<String, Double> base) {
        this.base = base;
    }

    // Note: this comparator imposes orderings that are inconsistent with
    // equals.
    public int compare(String a, String b) {
        if (base.get(a) >= base.get(b)) {
            return -1;
        } else {
            return 1;
        } // returning 0 would merge keys
    }
}

Output looks like this:

Words: 9
Chars: 59
{ =16.0, h=7.0, i=5.0, r=4.0, c=4.0, �=3.0, s=3.0, o=3.0, l=3.0, f=3.0, ,=2.0, w=1.0, u=1.0, n=1.0, m=1.0, b=1.0, a=1.0}

The output of "sorted_map.toString()" is not really nice, so I wrote a quick output method:

static void output(TreeMap<String, Double> sm) {

        String map = sm.toString();

        if (map.length() > 2) { //If the map is empty it looks like this: {}

            map = map.substring(1, map.length() - 1); //cutting the leading and closing { }

            String[] charCount = map.split(", "); //Splitting

            //And then formatting:
            for (String string : charCount) {
                if (string.charAt(0) == ' ') {

                    string = string.substring(1, string.length() - 2);
                    string = " " + string.substring(0, 1) + " " + string.substring(1, string.length());
                    System.out.println("SPACE" + string);

                } else {

                    string = string.substring(0, string.length() - 2);
                    string = string.substring(0, 1) + " " + string.substring(1, 2) + " "
                            + string.substring(2, string.length());
                    System.out.println(string);
                }
            }

        }

    }

Which you call like so:

    System.out.println("Words: " + totalWords);
    System.out.println("Chars: " + totalChars);
    System.out.println();
    //System.out.println(sorted_map.toString()); <--- old
    output(sorted_map);

And the Output looks like this:

Words: 9
Chars: 60

SPACE = 8
R = 6
T = 5
E = 5
A = 5
N = 3
U = 2
O = 2
M = 2
L = 2
I = 2
H = 2
. = 1
Z = 1
Y = 1
X = 1
W = 1
V = 1
S = 1
Q = 1
P = 1
K = 1
J = 1
G = 1
F = 1
D = 1
C = 1
B = 1

And there you go, it got a little bit messy (the comparator breaks the "TreeMap.get" method so I had to build a workaround using substrings) but I hope that this will somewhat help you :)

Eric F.
  • 86
  • 5
  • on this line ValueComparator bvc = new ValueComparator(count) . theres an error. its says non statice variable this cannot be referenced from static context – David Jul 24 '16 at 06:01
  • Okay, I just fixed 2 small mistakes in the code, but I don't really know why it would tell you that something isn't static... if you declare it inside the main() method it should always be static. I just copy-pasted the code again and it works fine for me – Eric F. Jul 24 '16 at 06:17
  • oh stupid me. it works fine now. except the call part. i can run the program. and it shows the result but there is some errors. – David Jul 24 '16 at 06:43
  • could you do me a favor ? – David Jul 24 '16 at 10:02
  • Depends on the favor, maybe we should move this conversation to email if it isn't about this topic: fingereric@web.de – Eric F. Jul 24 '16 at 10:34