前缀码判定

前缀码:任何一个字符的编码都不是同一字符集中另一个字符的编码的前缀。

请编写一个程序,判断输入的n个由1和0组成的编码是否为前缀码。如果这n个编码是前缀码,则输出"YES”;否则输出第一个与前面编码发生矛盾的编码。

输入:
第1行为n(表示下面有n行编码)
第2~n+1行为n个由0或1组成的编码

输出:判断结果

例如,如果输入:

5

00

01

10

110

111

每一个字符均不是其他字符编码的前缀,所以,输出:YES

再如,如果输入:

5

00

01

10

110

11

编码11与前面的编码110的前缀,所以,输出:11

测试输入期待的输出时间限制内存限制额外进程
测试用例 1以文本方式显示
  1. 5↵
  2. 00↵
  3. 01↵
  4. 10↵
  5. 110↵
  6. 111↵
以文本方式显示
  1. YES↵
1秒64M0
测试用例 2以文本方式显示
  1. 5↵
  2. 00↵
  3. 01↵
  4. 10↵
  5. 110↵
  6. 11↵
以文本方式显示
  1. 11↵
1秒64M0
测试用例 3以文本方式显示
  1. 5↵
  2. 00↵
  3. 01↵
  4. 10↵
  5. 11↵
  6. 111↵
以文本方式显示
  1. 111↵
1秒64M0
测试用例 4以文本方式显示
  1. 5↵
  2. 111↵
  3. 110↵
  4. 10↵
  5. 01↵
  6. 00↵
以文本方式显示
  1. YES↵
1秒64M0
测试用例 5以文本方式显示
  1. 8↵
  2. 00↵
  3. 010↵
  4. 0110↵
  5. 0111↵
  6. 10↵
  7. 110↵
  8. 1110↵
  9. 1111↵
以文本方式显示
  1. YES↵
1秒64M0
测试用例 6以文本方式显示
  1. 8↵
  2. 00↵
  3. 010↵
  4. 0110↵
  5. 0111↵
  6. 10↵
  7. 11↵
  8. 1110↵
  9. 111↵
以文本方式显示
  1. 1110↵
1秒64M0

代码如下:

        比较简单注释就只写了下思路,其实就是哈夫曼树,以后应该要学。也有可能是我上课睡觉听漏了,说不定已经教了。

        需要注意为假的判定。

        也可以用数组写。

/*
Huffman Tree(哈夫曼树),树干即编码,路径长度即编码长度.
根据二叉树特性通过树干路径进行编码(左分支赋予0,右分支赋予1).
构成前缀编码的形式,即一组编码中任一编码都不是其他任何一个编码的前缀.
那么这道题也就是考虑根据编码能否还原出一个哈夫曼树的问题,
如果能还原出一个哈夫曼树,那么就是一组编码中任一编码都不是其他任何一个编码的前缀
*/
#include <iostream>
#include <string>
using namespace std;
struct HFTree
{
    bool flag;
    HFTree *left;
    HFTree *right;
    HFTree() : flag(false), left(nullptr), right(nullptr) {}
};

bool isPrefixCode(const string &str, HFTree *&root)
{
    HFTree *Root = root;
    for (char ch : str)
    {
        if (ch == '0')
        {
            if (Root->left == nullptr)
                Root->left = new HFTree;
            Root = Root->left;
            if (Root->flag)
                return false;
        }
        else
        {
            if (Root->right == nullptr)
                Root->right = new HFTree;
            Root = Root->right;
            if (Root->flag)
                return false;
        }
    }
    Root->flag = true;
    return !Root->left && !Root->right;
}

int main()
{
    int n;
    cin >> n;
    HFTree *root= new HFTree;
    while (n--)
    {
        string str;
        cin >> str;
        if (!isPrefixCode(str, root))
        {
            cout << str << endl;
            return 0;
        }
    }
    cout << "YES" << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值