一、题目描述
从文件中读入一段二进制数,进行HDB3编码(假设第一个非零码是 +1),打印输出在控制台
二、HDB3编码规则
HDB3码的全称是三阶高密度双极性码.它是AMI码的一种改进型,改进目的是为了保持AMI码的优点而克服其缺点,使连零个数不超过三个。其编码规则如下:
- 先检查消息码的连零个数。当连零数目小于等于3时,则与AMI码的编码规则一样
- 当连零数目超过3个时,则将每4个连零化作一小节,用
000V 替代,V (取值 +1 或 -1 )应与其前一个相邻的非 0 脉冲的极性相同(因为这破坏了极性交替的规则,所以V称为破坏脉冲)。 - 相邻的V码极性必须交替。当V码取值能满足 (2) 中的要求但不能满足此要求时,则将
0000 用 B00V 替代,B的取值与后面的V的脉冲一致,用于解决此问题。因此,B称为调节脉冲 - V 码后面的传号码极性也要交替。例如
消息码: 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 AMI码: -1 0 0 0 0 +1 0 0 0 0 -1 +1 0 0 0 0 0 0 0 0 -1 +1 HDB3码: -1 0 0 0 -V +1 0 0 0 +V -1 +1 -B 0 0 -V +B 0 0 +V -1 +1
其中:±V 脉冲 和 ±B 脉冲 与 ±1 脉冲波形相同,用 V 或 B 符号表示的目的是为了示意该非零码是由原信码中的 0 变换而来的。
四、解题思路
- 当编码过程中没有出现连零的情况时,按照AMI编码算法,使 1 进行 正负交替,0 保持不变,具体我们可以定义变量来记录 1 出现的个数,以此题为例,我们的第奇数个1的极性为正,第偶数个1的极性就为负。
- 当编码过程中出现了连零的情况,我们定义变量来记录连零的个数,当连零个数大于等于4时,将四个连零中的第四个零修改为 破坏码V 并判断 V 的极性。
- 当只有一个破坏码时 V 的极性必定和其相邻的非零数的极性相同。
- 当有多个 破坏码V 时,就要使 V 的极性交替,我们可以定义集合来存储破坏码,并将这次出现的破坏码和上一次出现的破坏码的极性进行比较,从而确定其极性。
- 如果这次出现的破坏码极性和上次不同,则直接修改四个连零中的第四个零为破坏码,否则 我们要修改破坏码的极性并引入 调节码B ,B 的极性 和 修改后 V 的极性相同,然后 将 四个连零中的第一个零修改为调节码 B。
注意:当出现破坏码以后,之后的编码过程中的 1 的极性要受到 前一个 1 或 V 的极性的影响。
三、核心示例代码
public void HDB3(char[] buffer, int len) {
int count_0 = 0;
int count_1 = 0;
int count_v = 0;
int destroy_v = 1;
ArrayList<Integer> integers = new ArrayList<>();
String bin[] = new String[len];
for (int i = 0; i < len; i++) {
if (buffer[i] == '1') {
count_0 = 0;
count_1++;
bin[i] = ((count_1 & 0x01) == 1) ? "1" : "-1";
} else {
count_0++;
if (count_0 >= 4) {
count_0 = 0;
count_v++;
if (count_v == 1) {
destroy_v = ((count_1 & 0x01) == 1) ? 1 : -1;
integers.add(destroy_v);
bin[i] = (destroy_v == 1) ? "V" : "-V";
count_1 = (destroy_v == 1) ? 1 : 2;
} else if (count_v > 1) {
if(bin[i - 4] == "1" || bin[i - 4] == "-1"){
destroy_v = (bin[i - 4] == "1") ? 1 : -1;
}else if(bin[i - 4] == "V" || bin[i - 4] == "-V"){
destroy_v = (bin[i - 4] == "V") ? 1 : -1;
}
if (destroy_v != integers.get(count_v - 2)) {
integers.add(destroy_v);
bin[i] = (destroy_v == 1) ? "V" : "-V";
count_1 = (destroy_v == 1) ? 1 : 2;
} else if (destroy_v == integers.get(count_v - 2)) {
destroy_v = -destroy_v;
integers.add(destroy_v);
bin[i] = (destroy_v == 1) ? "V" : "-V";
bin[i - 3] = (destroy_v == 1) ? "B" : "-B";
count_1 = (destroy_v == 1) ? 1 : 2;
}
}
} else {
bin[i] = "0";
}
}
}
System.out.println("编码后:");
for (String values : bin) {
System.out.print(values + " ");
}
}
四、完整代码
package com.easy.java;
import org.junit.Test;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class HDB3Test {
@Test
public void HDB3Test() {
FileReader fileReader = null;
try {
fileReader = new FileReader(new File("HDB3.txt"));
char[] buffer = new char[1024];
int len = 0;
while ((len = fileReader.read(buffer)) != -1) {
System.out.println("编码前:");
for (char key : buffer) {
System.out.print(key + " ");
}
System.out.println();
HDB3(buffer, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileReader != null) {
fileReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void HDB3(char[] buffer, int len) {
int count_0 = 0;
int count_1 = 0;
int count_v = 0;
int destroy_v = 1;
ArrayList<Integer> integers = new ArrayList<>();
String bin[] = new String[len];
for (int i = 0; i < len; i++) {
if (buffer[i] == '1') {
count_0 = 0;
count_1++;
bin[i] = ((count_1 & 0x01) == 1) ? "1" : "-1";
} else {
count_0++;
if (count_0 >= 4) {
count_0 = 0;
count_v++;
if (count_v == 1) {
destroy_v = ((count_1 & 0x01) == 1) ? 1 : -1;
integers.add(destroy_v);
bin[i] = (destroy_v == 1) ? "V" : "-V";
count_1 = (destroy_v == 1) ? 1 : 2;
} else if (count_v > 1) {
if(bin[i - 4] == "1" || bin[i - 4] == "-1"){
destroy_v = (bin[i - 4] == "1") ? 1 : -1;
}else if(bin[i - 4] == "V" || bin[i - 4] == "-V"){
destroy_v = (bin[i - 4] == "V") ? 1 : -1;
}
if (destroy_v != integers.get(count_v - 2)) {
integers.add(destroy_v);
bin[i] = (destroy_v == 1) ? "V" : "-V";
count_1 = (destroy_v == 1) ? 1 : 2;
} else if (destroy_v == integers.get(count_v - 2)) {
destroy_v = -destroy_v;
integers.add(destroy_v);
bin[i] = (destroy_v == 1) ? "V" : "-V";
bin[i - 3] = (destroy_v == 1) ? "B" : "-B";
count_1 = (destroy_v == 1) ? 1 : 2;
}
}
} else {
bin[i] = "0";
}
}
}
System.out.println("编码后:");
for (String values : bin) {
System.out.print(values + " ");
}
}
}
五、测评结果
- 测评实例2:
1000010000110000000011
- 测评实例3:
010111000011010110000011110101110000101110000001011000000000000111010
|