#java #huffman-code
Вопрос:
EDIT: As pointed out by dratenik, this was indeed a design error and it could have easily been solved by removing any instances of T from my class and replacing them with chars and Characters where needed. I was stubborn though, and wanted to find a way to make it work with generics, and dratenik ALSO pointed out how to solve it (by sending instances of T to the method instead of trying to use chars directly), so huge thanks to them!
I don't know how to close questions or flag them as solved, but consider it solved! The new code is as follows:
public void fileDecoding(File oldFile, File newFile, PriorityQueue<T> pq) throws Exception{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(oldFile));
FileWriter fW = new FileWriter(newFile);
if(newFile.canRead() amp;amp; newFile.canWrite()) {
root = new Node(null);
convertCodeToTree(root, bis, pq);
bis.read();
decodeText(root, bis, fW);
}
else throw new Exception("No permissions to read and write to file");
fW.close();
bis.close();
}
private void convertCodeToTree(Node node, BufferedInputStream bis, PriorityQueue<T> pq) throws Exception{
int readChar = bis.read();
if(readChar != -1 amp;amp; (char) readChar != 'n'){
if(readChar == '0'){
node.left = new Node(null);
convertCodeToTree(node.left, bis, pq);
node.right = new Node(null);
convertCodeToTree(node.right, bis, pq);
}
if(readChar == '1'){
for(int i = 0; i < 8; i ) bis.read();
node.data = pq.dequeue();
}
}
}
THIS HAS BEEN SOLVED, but it might help someone with the same problem as me, so I'm not erasing it.
У меня есть задание создать с нуля реализацию кодирования Хаффмана, используя классы и методы, также созданные с нуля.
Вся часть сжатия прошла гладко, но, пытаясь написать метод для распаковки тестового файла, я столкнулся с действительно раздражающей проблемой. Я попытался поискать в Google способы ее решения, но не смог найти, поэтому решил написать здесь. Простите за любые ошибки, английский-не мой родной язык.
(Кроме того, быстрое редактирование, я удалил Символ расширения. Это была неудачная попытка решить проблему, и она не сработала)
public class HuffmanBST<T extends Comparable<T>>{
class Node{
private T data;
private Node left, right;
Node(T data){
this.data = data;
this.left = null;
this.right = null;
}
Node(Node left, Node right){
this.left = left;
this.right = right;
}
}
public void readFromFile(File file) throws Exception{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
BufferedReader br = new BufferedReader(new FileReader(file));
String treeBinary = br.readLine();
int i = 0;
convertCodeToTree(root, treeBinary, i);
decodeText(root);
bis.close();
}
private void convertCodeToTree(Node node, String firstline, int index){
char data = firstline.charAt(index);
if(data == 0) {
node = new Node(null);
convertCodeToTree(node.left, firstline, index );
convertCodeToTree(node.right, firstline, index );
}
if(data == 1){
String binaryToString = "";
int i = 0;
while(i < 8){
index ;
binaryToString = firstline.charAt(index);
i ;
}
char stringToChar = (char) Integer.parseInt(binaryToString, 2);
node = new Node(stringToChar); // This gives a compile-time error
}
}
Это метод, который я писал для восстановления дерева Хаффмана из уже сжатого текстового файла, но он выдает ошибку во время компиляции:
'Node(T)' in 'HuffmanBST.Node' cannot be applied to '(char)'
Я предполагаю, что это связано с тем, что мой класс HuffmanBST принимает общее значение T и присваивает его значению данных узла, и теперь узел не хочет создаваться, потому что он не может знать наверняка, что такое T до выполнения. Но у меня есть другой метод, который в основном делает то же самое, но там он работает без проблем и ошибок.
public void buildTree(PriorityQueue<T> frequencies){
PriorityQueue<Node> huffmanPQ = new PriorityQueue<>();
while(!frequencies.isEmpty()) huffmanPQ.enqueue(frequencies.getPriority(),
new Node(frequencies.dequeue())); // Doesn't throw a compile-time error.
while(huffmanPQ.size() > 1){
int weight1 = huffmanPQ.getPriority(); Node n1 = huffmanPQ.dequeue();
int weight2 = huffmanPQ.getPriority(); Node n2 = huffmanPQ.dequeue();
Node newNode = new Node(n1, n2);
huffmanPQ.enqueue((weight1 weight2), newNode);
}
root = huffmanPQ.dequeue();
}
Так что же я делаю не так? Спасибо за любую помощь.
Комментарии:
1. Какой смысл иметь параметр типа, который расширяет символ?
2. Чтобы расширить комментарий @vincendep: класс
Character
являетсяfinal
и, следовательно, не может быть подклассом.3. Тебе нужно
T
, все, что у тебя есть, — этоchar
. Где — то может быть ошибка в проектировании. Имеет ли смысл, чтобы эта вещь была общей и агностической ?T
4. @dratenik Я не совсем уверен, что в этом проблема (см. Эту демонстрацию Ideon, которая — учитывая вашу аргументацию — не должна работать). Однако я не совсем уверен, в чем разница между демонстрацией и предоставленным кодом. Обычно должен включаться автоматический(un)бокс.
5. Если вы действительно хотите, чтобы ХаффманБСТ был агностиком в отношении T, вызывающему объекту convertCodeToTree (/readFromFile), возможно, потребуется предоставить внешнюю вещь, которая преобразует фрагменты текста в экземпляры T? (ХаффманБСТ не знает, что такое конкретный тип T и как его построить, вызывающий может)