二十一、前缀码判定
二十一、前綴碼判定
文章目錄
- 二十一、前綴碼判定
- 題目描述
- 解題思路
- 上機代碼
題目描述
前綴碼:任何一個字符的編碼都不是同一字符集中另一個字符的編碼的前綴。
請編寫一個程序,判斷輸入的n個由1和0組成的編碼是否為前綴碼。如果這n個編碼是前綴碼,則輸出"YES”;否則輸出第一個與前面編碼發(fā)生矛盾的編碼。
輸入:
第1行為n(表示下面有n行編碼)
第2~n+1行為n個由0或1組成的編碼
**輸出:**判斷結(jié)果
例如,如果輸入:
5
00
01
10
110
111
每一個字符均不是其他字符編碼的前綴,所以,輸出:YES
再如,如果輸入:
5
00
01
10
110
11
編碼11與前面的編碼110的前綴,所以,輸出:11
| 測試用例 1 | 5 00 01 10 110 111 | YES | 1秒 | 64M | 0 |
| 測試用例 2 | 5 00 01 10 110 11 | 11 | 1秒 | 64M | 0 |
| 測試用例 3 | 5 00 01 10 11 111 | 111 | 1秒 | 64M | 0 |
| 測試用例 4 | 5 111 110 10 01 00 | YES | 1秒 | 64M | 0 |
| 測試用例 5 | 8 00 010 0110 0111 10 110 1110 1111 | YES | 1秒 | 64M | 0 |
| 測試用例 6 | 8 00 010 0110 0111 10 11 1110 111 | 1110 | 1秒 | 64M | 0 |
解題思路
所謂前綴碼的判定,本質(zhì)上是二叉樹的建樹問題。令二叉樹的左子樹都代表1,遇到 1 都向左走;右子樹都代表0,遇到 0 都向右走。
對于全新的沒有前綴的字符編碼,則二叉樹中建立對應(yīng)分支,分支除了最后一個結(jié)點外的所有結(jié)點值都為0,僅最后一個結(jié)點值為1。
字符編碼是前綴碼的話,如果在分支的行進過程中碰到值為 1 的結(jié)點,則當前字符編碼存在前綴碼;如果編碼遍歷完成,但是最后一個字符沒有新建結(jié)點,則當前字符編碼是別人的前綴碼。
對于前綴碼,我們用一個 flag 進行標記。當 flag 為 1 時表示存在前綴碼,輸出第一個前綴碼 prefix。如果全部判斷完成,flag 仍為0,則沒有前綴碼。
上機代碼
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<queue> #include<algorithm> using namespace std; typedef struct NODE {int data;struct NODE *lchild;struct NODE *rchild; }node,*Tree;int main() {int n = 0;char str[100010], prefix[100010];int flag = 0;Tree bit, T;bit = (Tree)malloc(sizeof(node));//初始化bit->data = 0;bit->lchild = NULL;bit->rchild = NULL;cin >> n;while(n--){memset(str, 0, sizeof(str));cin >> str;int len = strlen(str);if (flag == 1) //存在前綴碼后面都不用判斷了,讀取編碼后直接跳出循環(huán)continue;strcpy(prefix, str);//保存第一個前綴碼T = bit;//每次變回根節(jié)點初始化狀態(tài)for (int i = 0; i < len; i++){if (str[i] == '1') //1向左走{if (T->lchild == NULL)//左子樹新建結(jié)點{T->lchild = (Tree)malloc(sizeof(node));T = T->lchild;T->lchild = NULL;T->rchild = NULL;if (i == len - 1)T->data = 1;elseT->data = 0;}else{if (T->lchild->data == 1 || i == len - 1)//存在前綴碼{flag = 1;break;}elseT = T->lchild;}}else //0向右走{if (T->rchild == NULL)//右子樹新建結(jié)點{T->rchild = (Tree)malloc(sizeof(node));T = T->rchild;T->lchild = NULL;T->rchild = NULL;if (i == len - 1)T->data = 1;elseT->data = 0;}else{if (T->rchild->data == 1 || i == len - 1){flag = 1;break;}elseT = T->rchild;}}}}if (flag == 0)//沒有前綴碼cout << "YES" << endl;elsecout << prefix << endl;//system("pause");return 0; }總結(jié)
- 上一篇: 二十、 二叉树的同构
- 下一篇: 二十三、图的广度优先遍历