Java, объективировать уникальные символы из файла и подсчитывать вхождения с помощью метода increment () символьного объекта - PullRequest
0 голосов
/ 13 мая 2018

Я работаю над Java-программой, которая принимает текстовый файл в качестве входных данных, создает объект «CharacterFrequency» для каждого символа и считает количество вхождений каждого символа. До сих пор я построил класс для строительных объектов, который кажется функциональным в его текущей форме, но у меня возникли проблемы с логическим потоком программ в моем основном цикле. Я не могу понять, как структурировать цикл for if else while и т. Д. Для циклического перебора символов и увеличения счетчика для каждого объекта.

Некоторые попросили уточнить, поэтому позвольте мне попытаться выразить это другими словами.

Начиная с первого символьного объекта, если мы перебираем массив charArray, я сначала вижу новый символ, мне нужно создать для него новый объект CharacterFrequency, а затем продолжить итерацию по charArray, найти другие вхождения и считать их путем увеличения с помощью метода increment () класса CharacterFrequency для конкретного символа, найденного в документе. Конечным результатом является объект CharacterFrequency для каждого найденного символа и счетчик вхождения.

Любая помощь будет высоко ценится. Спасибо.

Основной цикл:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.io.FileReader;
import java.io.IOException;

public class CharFreqMain {

    public static void main(String[] args) throws IOException {

        //declare variables and object types
        ArrayList<CharacterFrequency> charObjectsArray = new ArrayList<CharacterFrequency>();


        //try to open file and if not found catch file not found exception and exit
        try {
            //create scanner object of text file BufferedReader for efficiency
            BufferedReader br = new BufferedReader(new FileReader("C:/text.txt"));

            //create string to store each line
            String s;

            //while loop reads each line of BufferedReader br and creates string
            while ((s = br.readLine()) != null) {

                //create character array from string s
                char[] charArray = s.toCharArray();
                CharacterFrequency newcharobj = new CharacterFrequency();
                System.out.println(charArray);

                //iterate though character array
                for (char c : charArray) {

                    //check if the current object has the same character being checked and increment
                    if (c == newcharobj.getCharacter()) {
                        newcharobj.increment(1);
                    }
                    else {
                        newcharobj.setCharacter(c);
                    }

                    charObjectsArray.add(newcharobj);
                }
            }

            //close BufferedReader br
            br.close();
        }

        //code speaks for itself
        catch (FileNotFoundException e) {
            System.out.println("File Not Found");
            System.exit(0);
        }

        finally {

            //iterate through objects in charObjs Array and print characters and freqs to console
            for (CharacterFrequency charObject : charObjectsArray) {

                try {
                    System.out.println(charObject.getCharacter() + " | " + charObject.getFrequency());

                }
                catch(NullPointerException e) {

                }

                //build write to file Here
            }
        }
    }
}

CharacterFrequency Class:

public class CharacterFrequency {

    char character;
    int frequency;
    int i;
    int freq = 0;

    public char getCharacter() {
        return this.character;
    }

    public void setCharacter(char character) {
        this.character = character;
    }

    public int getFrequency() {
        return this.frequency;
    }

    public void setFrequency(int frequency) {
        this.frequency = frequency;
    }

    public void increment(int i) {
        freq = freq + i;
    }

}

В этом разделе кода мне нужна помощь:

        //create character array from string s
        char[] charArray = s.toCharArray();
        CharacterFrequency newcharobj = new CharacterFrequency();
        System.out.println(charArray);

        //iterate though character array
        for (char c : charArray) {

            //check if the current object has the same character being checked and increment
            if (c == newcharobj.getCharacter()) {
                newcharobj.increment(1);
            }
            else {
                newcharobj.setCharacter(c);
            }

            charObjectsArray.add(newcharobj);
        }
    }

1 Ответ

0 голосов
/ 13 мая 2018

Из того, что я могу понять, кажется, что вы хотите прочитать каждую строку, а затем построить объект CharacterFrequency для каждого символа и сколько раз это происходит.

Это может быть легко достигнуто с помощью API потока Java:

List<CharacterFrequency> resultSet =
                new BufferedReader(new FileReader("C:/text.txt"))
                .lines()
                .flatMap(s -> s.chars().mapToObj(a -> (char)a))
                .collect(Collectors.groupingBy(Function.identity(),
                        Collectors.summingInt(e -> 1)))
                .entrySet()
                .stream()
                .map(e -> new CharacterFrequency(e.getKey(), e.getValue()))
                .collect(Collectors.toCollection(ArrayList::new));

Предполагается, что у вас есть конструктор в классе CharacterFrequency следующим образом:

public CharacterFrequency(char character, int frequency) {
      this.character = character;
      this.frequency = frequency;
}

Расшифровка вышеуказанного решения:

  • Метод lines из приведенного выше BufferedReader дает Stream<String>, где элементами являются строки, прочитанные из этого BufferedReader.
  • .flatMap(s -> s.chars().mapToObj(a -> (char)a)) преобразует каждую строку в Stream<Character>, который flatMap затем объединяет все вложенные Stream<Stream<Character>> в один Stream<Character>.
  • С .collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(e -> 1))) мы получаем Map<Character, Integer>, где ключом являются символы, а целое число представляет количество вхождений данного символа.
  • Затем мы создаем поток из entrySet с .entrySet().stream() и создаем CharacterFrequency объекты с .map(e -> new CharacterFrequency(e.getKey(), e.getValue()))
  • Наконец, мы собираем в реализацию списка .collect(Collectors.toCollection(ArrayList::new));
...