[信息论]唯一可译码的判决算法实现(UDC)

唯一可译码的判决算法实验(UDC)

使用A. A. Sardinas G. W. Patterson 设计的判断法进行判断,具体流程(见流程图Fig. 1)如下:

1. 输入原始数据,并用ArrayList()类存储起来;

2. 在使用规则之前,先判断是否奇异,如果奇异,将没有进行后续判断的必要,如果非奇异,进入第3步;否则结束程序,输出结果(奇异);

3. 第一次寻找,调用自己设定的seekarray),在初始数据中找到符合条件的尾随后缀,然后进入第4步;

4. 通过第一次寻找,可以得到一个arr数组,如果该数组为空,那么就没有必要再进行下去,已经证明找不到更多的尾随后缀了,直接进入第6步;否则进入第5步;

5. 通过第一次的寻找,已经得到基本的arr,但是arr是用于判断的,所以首先克隆arrarrclone中,并且将arr清空,调用seekarrayarrclone,再将arrclone的字符串和原始数据进行对比,再次得到arr,如果arr为空,进入第6步,否则循环第5步;               

6. 得到了S,若S为空,则证明不存在尾随后缀,则为即时码,输出结果;若不为空,将原始数据arrayS进行对比,若有相同的字符串,则不是唯一可译码,反之,是唯一可译码。

 [信息论]唯一可译码的判决算法实现(UDC)_第1张图片

 

Fig. 1算法流程图

 

代码运行结果如下:

1

 [信息论]唯一可译码的判决算法实现(UDC)_第2张图片

结果一致;

2

 [信息论]唯一可译码的判决算法实现(UDC)_第3张图片

由文献[2]提供的办法,我们知道,10可以组成10,所以不是唯一可译码;

 

3

 [信息论]唯一可译码的判决算法实现(UDC)_第4张图片

与预期结果一致;

 

4

 [信息论]唯一可译码的判决算法实现(UDC)_第5张图片

与预期结果一致;

 

5

 [信息论]唯一可译码的判决算法实现(UDC)_第6张图片

与预期结果一致。


参考代码如下。

import java.util.*;

public class udcjudge {
	public static ArrayList<String> array = new ArrayList<String>();// 用于存放原始数据
	public static ArrayList<String> arr = new ArrayList<String>();// 用于存放本次产生的尾随后缀
	public static ArrayList<String> arrclone = new ArrayList<String>();// 用于存放数据,克隆arr数组
	public static ArrayList<String> S = new ArrayList<String>();// 用于存放尾随后缀(dangling
																// suffix)
	public static boolean flag = false;// 判断S和array是否有同样的字符,从而得出是否唯一可译
	public static boolean flag2 = false;// 判断是否奇异

	// 用于第一次寻找
	public void seek(ArrayList<String> a) {
		int length = a.size();
		for (int i = 0; i < length; i++)
			for (int j = 0; j < length; j++)
				if (a.get(i).length() < a.get(j).length()) {
					if (a.get(i).equals(
							a.get(j).substring(0, a.get(i).length()))) {
						String str1 = a.get(j).substring(a.get(i).length());
						boolean flag1 = true;
						for (int k = 0; k < S.size(); k++) {
							if (S.get(k).equals(str1)) {
								flag1 = false;
								break;
							}
						}
						if (flag1 == true && str1.equals("") == false) {
							S.add(str1);
							arr.add(str1);
						}
					}
				}
	}

	// 指的是第一次以后的寻找
	public void seek(ArrayList<String> a, ArrayList<String> ar) {
		arr.clear();// 首先清空上次残留,若本次之后还是空,则找到所有的后缀,可跳出循环
		int length = a.size();
		int length1 = ar.size();
		// 判断,这是重要部分
		for (int i = 0; i < length; i++)
			for (int j = 0; j < length1; j++) {
				if (a.get(i).length() < ar.get(j).length()) {
					if (a.get(i).equals(
							ar.get(j).substring(0, a.get(i).length()))) {
						String str1 = ar.get(j).substring(a.get(i).length());
						boolean flag1 = true;
						for (int k = 0; k < S.size(); k++) {
							if (S.get(k).equals(str1)) {
								flag1 = false;
								break;
							}
						}
						// 符合条件,可以添加进入S和arr
						if (flag1 == true && str1.equals("") == false) {
							S.add(str1);
							arr.add(str1);
						}
					}
				} else// 和if语句一样,a.get(i)和ar.get(j)具有同样的地位
				{
					if (ar.get(j).equals(
							a.get(i).substring(0, ar.get(j).length()))) {
						String str1 = a.get(i).substring(ar.get(j).length());
						boolean flag1 = true;
						for (int k = 0; k < S.size(); k++) {
							if (S.get(k).equals(str1)) {
								flag1 = false;
								break;
							}
						}
						if (flag1 == true && str1.equals("") == false) {
							S.add(str1);
							arr.add(str1);
						}
					}
				}
			}
	}

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.print("请输入C(X)序列中字符串的个数:");
		int N = input.nextInt(); // N 代表该有限序列中信源码的个数
		String[] str = new String[N];// str[] 依次用于存放信源码
		System.out.print("请依次输入C(X)序列中的各个字符串:");
		for (int i = 0; i < N; i++) {
			str[i] = input.next();
			array.add(str[i]);
		}
		udcjudge udc = new udcjudge();
		for (int i = 0; i < array.size() - 1; i++)
			for (int j = i + 1; j < array.size(); j++) {
				if (array.get(i).equals(array.get(j))) {
					flag2 = true;
					break;
				}
			}
		if (flag2)
			System.out.println("该有限序列C(X)是奇异的。");
		else {
			udc.seek(array);// 第一次寻找
			while (arr.isEmpty() == false) {
				arrclone = (ArrayList<String>) arr.clone();// 克隆数据,后面有clear
				udc.seek(array, arrclone);
			}

			if (S.isEmpty())// 判断为空,所以可以输出为即时码,后续不用比较
				System.out.print("尾随后缀(dangling suffix)为空,所以C(X)是即时码。");
			else// 非空且非奇异,所以判断是否唯一可译
			{
				System.out.print("输出尾随后缀(dangling suffix)的集合:");
				Iterator it1 = S.iterator();
				while (it1.hasNext())
					// 迭代器输出输出所有尾随后缀的集合
					System.out.print(it1.next() + "   ");
				System.out.println();
				for (int i = 0; i < S.size(); i++)
					for (int j = 0; j < array.size(); j++)
						if (S.get(i).equals(array.get(j))) {
							flag = true;// 搜索到相同的,即可跳出
							break;
						}
				if (flag)
					System.out.println("该有限序列C(X)不是唯一可译码。");
				else
					System.out.println("该有限序列C(X)是唯一可译码。");
			}
		}
	}
}


你可能感兴趣的:(算法,唯一可译码)