Phone List(字典树)

电话号码一致性检查
本文介绍了一种使用Trie树算法来判断一组电话号码是否一致的方法。一致性指任一号码都不是另一号码的前缀,避免了拨号过程中的混淆。通过构建Trie树,算法在插入每个号码的同时检查是否出现前缀冲突。

Description

Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let's say the phone catalogue listed these numbers:

  • Emergency 911
  • Alice 97 625 999
  • Bob 91 12 54 26

In this case, it's not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob's phone number. So this list would not be consistent.

Input

The first line of input gives a single integer, 1 ≤ t ≤ 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 ≤ n ≤ 10000. Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.

Output

For each test case, output "YES" if the list is consistent, or "NO" otherwise.

Sample Input

2
3
911
97625999
91125426
5
113
12340
123440
12345
98346

Sample Output

NO
YES

 题意

  给定n个长度不超过10的数字串,问其中是否存在两个数字串S,T,使得S是T的前缀。有多组数据,数据组数不超过40.n<=10^4

思路

 考虑将所有的字符串构成一棵Trie,在构建过程中可以顺便判断答案。若当前串插入后没有新建任何结点,则当前串肯定是之前插入的某个串的前缀;若插入过程中,有某个经过的结点带有串尾标记,则之前插入的某个串是当前串的前缀。依据上述两种情况判断

代码

#include<stdio.h>
#include<string.h>
#define N 100005
#define Z 10
int ch[N][Z],tot,bo[N];
int Insert(char *s) //插入一个字符串同时判断答案
{
    int len=strlen(s);
    int u=1,flag=0,i;
    for(i=0;i<len;i++)
    {
        int c=s[i]-'0';
        if(!ch[u][c])
            ch[u][c]=++tot;
        else if(i==len-1)
            flag=1;  //没有插入任何新结点
        u=ch[u][c];
        if(bo[u])
           flag=1;  //经过某个有标记的结点
    }
    bo[u]=1;
    return flag;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,ans=0;
        char s[20];
        scanf("%d",&n); tot=1;
        memset(ch,0,sizeof(ch));
        memset(bo,0,sizeof(bo));
        while(n--)
        {
            scanf("%s",s);
            if(Insert(s)) ans=1;
        }
        if(ans)
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}

 

<think>我们被要求提供在Python中分行打印嵌套字典的示例代码。根据用户需求,我们需要打印嵌套字典,并且要求分行打印,即每个键值对单独一行,并且嵌套的部分也要有良好的格式。思路:1.我们可以使用递归的方法来处理嵌套字典。2.对于每一层,我们遍历字典的键值对。3.如果值是一个字典,则递归地打印这个字典,并增加缩进。4.如果是字典,就直接打印。但是注意:用户要求分行打印,所以我们希望输出是易读的,通常通过缩进来表示嵌套层次。我们将编写一个函数`pretty_print_nested_dict(d,indent=0)`,其中`d`是要打印的字典,`indent`表示当前的缩进级别。然而,我们也可以使用`json`模块的`dumps`方法,通过设置`indent`参数来美化输出,但这可能是用户想要的直接代码实现。但用户要求的是示例代码,所以我们可以提供两种方法:方法一:自己编写递归函数打印。方法二:使用json模块。由于嵌套字典中可能包含非字符串的键,以及各种类型的值,而json模块要求键是字符串,所以如果字典键字符串,使用json.dumps可能会出错。因此,我们首先考虑自己编写递归函数。自己编写递归函数需要注意:1.避免循环引用(这里我们假设没有循环引用,因为通常打印配置数据等会出现循环引用)。2.处理非字典的值。我们将按照以下格式打印:键:值如果值是字典,则递归打印,并增加缩进。示例字典:nested_dict={'key1':'value1','key2':{'subkey1':'subvalue1','subkey2':{'subsubkey1':'subsubvalue1'}},'key3':123}我们希望打印效果:key1:value1key2:subkey1:subvalue1subkey2:subsubkey1:subsubvalue1key3:123步骤:1.遍历字典的每个键值对。2.判断是否为字典类型(使用isinstance(value,dict))。3.如果是字典,则先打印键,然后换行,递归打印这个字典(缩进增加)。4.如果是字典,则打印键值。注意:缩进我们可以用空格,例如每层缩进4个空格。另外,我们也可以使用pprint模块,但用户要求的是分行打印嵌套字典,并且要求示例代码,所以我们自己实现一个。但是,考虑到用户可能希望看到多种方法,我们将提供两种方法:方法1:自定义递归函数方法2:使用pprint模块(它也可以处理嵌套字典,并且格式美观)由于pprint模块是标准库,我们可以直接使用,但它的输出格式是每行一个元素,并且缩进表示嵌套,非常符合要求。因此,我们可以这样:示例1:自定义递归函数示例2:使用pprint模块但是,用户要求的是“分行打印嵌套字典”,所以两种方法都可以。我们先写自定义递归函数的方法,然后再用pprint。另外,用户要求的是“示例代码”,所以我们将提供完整的代码示例。注意:如果字典中有列表或其他可迭代对象,我们可能也需要分行打印?但是用户只说了嵌套字典,所以我们暂时只处理字典。如果值是一个列表,里面可能包含字典,那么我们可以扩展递归函数来处理,但用户问题中只要求嵌套字典。为了简单,我们先处理字典嵌套,其他非字典类型直接打印。但是,根据引用[2][3]的内容,用户可能遇到多层嵌套的情况,所以我们的递归函数应该能够处理多层嵌套。下面我们提供代码示例。</think>### Python 中分行打印嵌套字典的方法 在 Python 中分行打印嵌套字典,可以使用递归方法或 `json` 模块来实现清晰的多层级显示。以下是两种常用方法: #### 方法一:递归函数实现(推荐) ```python def print_nested_dict(data, indent=0): """递归打印嵌套字典""" for key, value in data.items(): # 计算当前缩进 padding = ' ' * indent if isinstance(value, dict): # 如果值是字典,递归处理 print(f"{padding}{key}:") print_nested_dict(value, indent + 4) else: # 非字典值直接打印 print(f"{padding}{key}: {value}") # 示例字典 nested_dict = { 'user': { 'name': 'Alice', 'contact': { 'email': 'alice@example.com', 'phone': '123-4567' } }, 'system': { 'os': 'Windows', 'version': 11 } } # 调用函数分行打印 print_nested_dict(nested_dict) ``` **输出效果**: ``` user: name: Alice contact: email: alice@example.com phone: 123-4567 system: os: Windows version: 11 ``` #### 方法二:使用 json 模块格式化 ```python import json # 直接使用 json.dumps 的缩进格式化 formatted = json.dumps(nested_dict, indent=4) print(formatted) ``` **输出效果**: ```json { "user": { "name": "Alice", "contact": { "email": "alice@example.com", "phone": "123-4567" } }, "system": { "os": "Windows", "version": 11 } } ``` ### 关键点说明 1. **递归方法优势**: - 完全自定义输出格式(如替换冒号、调整缩进符号) - 可扩展处理非字典数据类型(列表、元组等) - 避免 JSON 格式化对非字符串键的限制 2. **JSON 方法优势**: - 单行代码快速实现 - 标准化的树形结构显示 - 支持 `ensure_ascii=False` 参数显示中文 3. **处理复杂嵌套**: ```python # 包含列表的嵌套字典示例 complex_dict = { 'project': 'Alpha', 'members': [ {'name': 'Bob', 'role': 'dev'}, {'name': 'Cara', 'role': 'designer'} ] } # 扩展递归函数处理列表 def print_nested(data, indent=0): padding = ' ' * indent if isinstance(data, dict): for k, v in data.items(): print(f"{padding}{k}:") print_nested(v, indent + 4) elif isinstance(data, list): for item in data: print_nested(item, indent) else: print(f"{padding}{data}") ``` ### 注意事项 1. 递归深度限制:Python 默认递归深度约 1000 层,超深嵌套需调整 `sys.setrecursionlimit()` 2. 循环引用检测:若字典存在循环引用(A 包含 B,B 又包含 A),递归会导致栈溢出 3. 自定义格式:可在递归函数中添加参数控制缩进符号(如 `→`)、颜色标记等增强可读性 > 通过合理选择递归或 JSON 方法,可以清晰展示嵌套字典的层级结构,这在处理配置文件、API 响应等场景尤为实用[^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值