// 3068K
282MS
Java
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Comparator;
import java.util.Arrays;
public class Main {
private static final int MAX = 27;
private static final char UNDER_SCORE = '_';
private class CharacterComparator implements Comparator<CharacterTreeNode> {
@Override
public int compare(CharacterTreeNode o1, CharacterTreeNode o2) {
return o1.num - o2.num;
}
}
private CharacterComparator mComparator;
private int[] mCharacterMap;
private int mStrLength;
// private class Character {
// public char content;
// public int num;
// public boolean isParentNode;
// }
private class CharacterTreeNode {
public CharacterTreeNode left;
public CharacterTreeNode right;
public int num;
public char content ;
};
private int mCharType;
private CharacterTreeNode[] mCharacterInfo;
public void preProcess(String str) {
for (int i = 0; i < MAX; i++) {
mCharacterInfo[i] = new CharacterTreeNode();
mCharacterInfo[i].left = null;
mCharacterInfo[i].right = null;
}
mStrLength = str.length();
for (int i = 0; i < MAX; i++) {
mCharacterMap[i] = 0;
}
byte[] byteArray = str.getBytes();
for (int i = 0; i < mStrLength; i++) {
if (byteArray[i] == UNDER_SCORE) {
mCharacterMap[MAX-1]++;
} else {
mCharacterMap[byteArray[i]-'A']++;
}
}
for (int i = 0; i < MAX-1; i++) {
if (mCharacterMap[i] != 0) { // this char appear
mCharacterInfo[mCharType].content = (char)(i + 'A');
mCharacterInfo[mCharType++].num = mCharacterMap[i];
}
}
if (mCharacterMap[MAX-1] != 0) {
mCharacterInfo[mCharType].content = '_';
mCharacterInfo[mCharType++].num = mCharacterMap[MAX-1];
}
}
private int mOptinalLength;
public void bypassTree(CharacterTreeNode node, int degree) {
if (node == null) {
return;
}
if (node.left == null && node.right == null) {
// System.out.println(node.content + " " + degree);
mOptinalLength += (degree-1)*(node.num);
} else {
bypassTree(node.left, degree + 1);
bypassTree(node.right, degree + 1);
}
}
public void solve(String str) {
mOptinalLength = 0;
mCharType = 0;
preProcess(str);
int treeNodeNum = mCharType;
while(treeNodeNum > 1) {
Arrays.sort(mCharacterInfo, 0, treeNodeNum, mComparator);
CharacterTreeNode leftTreeNode = mCharacterInfo[0];
CharacterTreeNode rightTreeNode = mCharacterInfo[1];
CharacterTreeNode sumTreeNode = new CharacterTreeNode();
sumTreeNode.num = leftTreeNode.num + rightTreeNode.num;
sumTreeNode.left = leftTreeNode.num < rightTreeNode.num ?
leftTreeNode : rightTreeNode;
sumTreeNode.right = leftTreeNode.num >= rightTreeNode.num ?
leftTreeNode : rightTreeNode;
mCharacterInfo[0] = sumTreeNode;
if (treeNodeNum > 2) {
mCharacterInfo[1] = mCharacterInfo[treeNodeNum-1];
}
treeNodeNum--;
}
bypassTree(mCharacterInfo[0], 1);
int orginalLength = mStrLength * 8;
if (mCharType == 1) {
mOptinalLength = mStrLength;
}
// java.text.DecimalFormat df = new java.text.DecimalFormat("#.#");
String result = String.format("%.1f", (double)orginalLength/mOptinalLength);
// System.out.println(orginalLength + " " + mOptinalLength + " " + ((int)(((double)orginalLength)/mOptinalLength*10))/10.0);
System.out.println(orginalLength + " " + mOptinalLength + " " + result);
}
public Main() {
mCharType = 0;
mOptinalLength = 0;
mCharacterInfo = new CharacterTreeNode[MAX];
for (int i = 0; i < MAX; i++) {
mCharacterInfo[i] = new CharacterTreeNode();
mCharacterInfo[i].left = null;
mCharacterInfo[i].right = null;
}
mComparator = new CharacterComparator();
mCharacterMap = new int[MAX];
}
public static void main(String[] args) {
Main solver = new Main();
Scanner input = new Scanner(System.in);
while(true) {
String str = input.next();
if (str.equals("END")) {
return;
}
solver.solve(str);
}
}
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Comparator;
import java.util.Arrays;
public class Main {
private static final int MAX = 27;
private static final char UNDER_SCORE = '_';
private class CharacterComparator implements Comparator<CharacterTreeNode> {
@Override
public int compare(CharacterTreeNode o1, CharacterTreeNode o2) {
return o1.num - o2.num;
}
}
private CharacterComparator mComparator;
private int[] mCharacterMap;
private int mStrLength;
// private class Character {
// public char content;
// public int num;
// public boolean isParentNode;
// }
private class CharacterTreeNode {
public CharacterTreeNode left;
public CharacterTreeNode right;
public int num;
public char content ;
};
private int mCharType;
private CharacterTreeNode[] mCharacterInfo;
public void preProcess(String str) {
for (int i = 0; i < MAX; i++) {
mCharacterInfo[i] = new CharacterTreeNode();
mCharacterInfo[i].left = null;
mCharacterInfo[i].right = null;
}
mStrLength = str.length();
for (int i = 0; i < MAX; i++) {
mCharacterMap[i] = 0;
}
byte[] byteArray = str.getBytes();
for (int i = 0; i < mStrLength; i++) {
if (byteArray[i] == UNDER_SCORE) {
mCharacterMap[MAX-1]++;
} else {
mCharacterMap[byteArray[i]-'A']++;
}
}
for (int i = 0; i < MAX-1; i++) {
if (mCharacterMap[i] != 0) { // this char appear
mCharacterInfo[mCharType].content = (char)(i + 'A');
mCharacterInfo[mCharType++].num = mCharacterMap[i];
}
}
if (mCharacterMap[MAX-1] != 0) {
mCharacterInfo[mCharType].content = '_';
mCharacterInfo[mCharType++].num = mCharacterMap[MAX-1];
}
}
private int mOptinalLength;
public void bypassTree(CharacterTreeNode node, int degree) {
if (node == null) {
return;
}
if (node.left == null && node.right == null) {
// System.out.println(node.content + " " + degree);
mOptinalLength += (degree-1)*(node.num);
} else {
bypassTree(node.left, degree + 1);
bypassTree(node.right, degree + 1);
}
}
public void solve(String str) {
mOptinalLength = 0;
mCharType = 0;
preProcess(str);
int treeNodeNum = mCharType;
while(treeNodeNum > 1) {
Arrays.sort(mCharacterInfo, 0, treeNodeNum, mComparator);
CharacterTreeNode leftTreeNode = mCharacterInfo[0];
CharacterTreeNode rightTreeNode = mCharacterInfo[1];
CharacterTreeNode sumTreeNode = new CharacterTreeNode();
sumTreeNode.num = leftTreeNode.num + rightTreeNode.num;
sumTreeNode.left = leftTreeNode.num < rightTreeNode.num ?
leftTreeNode : rightTreeNode;
sumTreeNode.right = leftTreeNode.num >= rightTreeNode.num ?
leftTreeNode : rightTreeNode;
mCharacterInfo[0] = sumTreeNode;
if (treeNodeNum > 2) {
mCharacterInfo[1] = mCharacterInfo[treeNodeNum-1];
}
treeNodeNum--;
}
bypassTree(mCharacterInfo[0], 1);
int orginalLength = mStrLength * 8;
if (mCharType == 1) {
mOptinalLength = mStrLength;
}
// java.text.DecimalFormat df = new java.text.DecimalFormat("#.#");
String result = String.format("%.1f", (double)orginalLength/mOptinalLength);
// System.out.println(orginalLength + " " + mOptinalLength + " " + ((int)(((double)orginalLength)/mOptinalLength*10))/10.0);
System.out.println(orginalLength + " " + mOptinalLength + " " + result);
}
public Main() {
mCharType = 0;
mOptinalLength = 0;
mCharacterInfo = new CharacterTreeNode[MAX];
for (int i = 0; i < MAX; i++) {
mCharacterInfo[i] = new CharacterTreeNode();
mCharacterInfo[i].left = null;
mCharacterInfo[i].right = null;
}
mComparator = new CharacterComparator();
mCharacterMap = new int[MAX];
}
public static void main(String[] args) {
Main solver = new Main();
Scanner input = new Scanner(System.in);
while(true) {
String str = input.next();
if (str.equals("END")) {
return;
}
solver.solve(str);
}
}
}
3068K 282MS Java
纯哈弗曼树水题,复习了下如何构造哈弗曼树。
两个注意:
1: 注意只有一种字母的情况,这种情况下哈弗曼树不适用
2: java的一定要注意,题目虽然没说四舍五入,但其实是要求四舍五入的,WA了好几次....
没有用优先级队列,为了继续训练java的基础操作,用的是每次合并完重新排序,每次合并完前两个节点,把第一个节点更新为合并出来的节点,第二个节点则和
队列最后一个节点互换(java全引用就是好,直接指过去就完了,如果只有两个节点,就不用了),下次重新排序,只不过范围-1. 直到最后只剩一个节点退出。
最后遍历形成的树,在每个叶子节点(每个要编码字符)计算其树高和个数的乘积,累加即可。
mark一下,以后再写个用了优先队列的版本.