前缀码判定

文章描述了一个编程问题,通过构建哈夫曼树来判断一组由1和0组成的编码是否为前缀码。如果编码可以形成一棵哈夫曼树且满足前缀性质,则输出YES,否则输出第一个矛盾编码。

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

请编写一个程序,判断输入的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;
}

### C语言实现验证电话号码合法性 在C语言中,可以通过多种方式来验证电话号码的合法性。以下是基于引用内容[^1]的一种实现方案: #### 逻辑说明 1. **输入处理**:通过`scanf`或其他输入函数获取用户输入的电话号码。 2. **字符校验**:遍历输入字符串,确保所有字符均为数字。 3. **长度校验**:根据中国的电话号码规则,判断输入的长度是否为3位或11位。 4. **特定规则校验**: - 对于11位手机号码,第一位必须为`1`,第二位需属于常见运营商前缀(如`3`, `5`, `7`, `8`)。 - 对于3位固定电话号码,第一位也应为`1`。 #### 示例代码 ```c #include <stdio.h> #include <ctype.h> #include <string.h> int main() { char s[100]; printf("请输入需要判断的号码数据(仅限数字类型):\n"); scanf("%s", s); // 字符校验 int length = strlen(s); for (int i = 0; i < length; i++) { if (!isdigit(s[i])) { printf("------您输入了错误数值,%s 不符合号码必要条件---------\n", s); return 0; } } // 长度校验与具体规则校验 if (length == 11) { // 判断11位手机号码 if (s[0] == '1') { if (s[1] == '3' || s[1] == '5' || s[1] == '7' || s[1] == '8') { printf("号码 %s 是合法的中国电话号码!\n", s); } else { printf("号码 %s 第二位不合法!\n", s); } } else { printf("号码 %s 第一位不合法!\n", s); } } else if (length == 3) { // 判断3位固定电话号码 if (s[0] == '1') { if (s[1] == '1' || s[1] == '2') { printf("号码 %s 是合法的中国电话号码!\n", s); } else { printf("号码 %s 第二位不合法!\n", s); } } else { printf("号码 %s 第一位不合法!\n", s); } } else { printf("号码 %s 的长度不符合要求!\n", s); } return 0; } ``` #### 功能解释 - 使用`isdigit()`函数逐一检查输入字符串中的每个字符是否为数字。 - 根据输入长度分别执行不同规则的校验逻辑。 - 输出详细的提示信息,帮助用户了解输入为何被判定为非法。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值