【计算机算法】【LeetCode】字符串排序---字典树Trie

 题目

20亿条字符串进行排序。每条字符串长度最大为255,字符范围为可见字符。

要求:最快的方法对其进行排序

分析

快排?归并?

何不试试字典树?

1) 应用场景:自动补全,拼写检查,

2) 时间复杂度为O(n)

代码

// Example program
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

const int gc_visibleCharNum = 92;
const int gc_beginCharIndex = 32;

class CDictTree
{
private:
    char m_bChar;
    bool m_isEnding;
    CDictTree * m_pNext[gc_visibleCharNum];
    
public:
    CDictTree()
    {
        m_bChar = 0;
        m_isEnding = false;
        for (int i = 0; i < gc_visibleCharNum; i++)
        {
            m_pNext[i] = nullptr;    
        }
    }

    // 插入单词(有点类似链表的插入):
    // 1) node指向根节点
    // 2) 从单词的第一个字符开始判断,该字符是否在节点指向的字母映射表中出现(不为nullptr空指针)
    // 3) 如果没有出现过就创建对应的内存空间,然后node指向对应字母的链接。
    // 4) 重复操作,直到该单词全部插入完,将最后的尾结点node->m_isEnding=true()(表示一个单词的结尾)。
    int insert(string value)
    {
        CDictTree *pNode = this;
        CDictTree *pNextNode = nullptr;
        char c = 0;
        size_t i = 0;
        for (i = 0; i < value.length(); i++)
        {
            c = value[i];
            pNextNode = pNode->m_pNext[c - gc_beginCharIndex];
            if (nullptr == pNextNode)
            {
                pNextNode = new CDictTree();
                pNextNode->m_bChar = c;
                pNode->m_pNext[c - gc_beginCharIndex] = pNextNode;
            }
            pNode = pNextNode;
        }
        pNode->m_isEnding = true;
        return 1;
    }

    // 查找单词是否在字典树中:
    // 1) node先指向根节点,
    // 2) 然后从单词的第一个字符开始判断,该字符是否在node指向的字母映射表中出现
    // 3) 如果没有出现直接return false,否则node指向对应字母的链接,
    // 4) 重复操作,直至单词全部查询完。
    // 5) 最后再判断node->m_isEnding == true?
    // 6) 如果不为true,则表示并不是单词的结尾(该单词没有出现在字典树中,只是前缀包含了该单词)。
    int search(string value)
    {
        CDictTree *pNode = this;
        CDictTree *pNextNode = nullptr;
        char c = 0;
        for (size_t i = 0; i < value.length(); i++)
        {
            c = value[i];
            pNextNode = pNode->m_pNext[c - gc_beginCharIndex];
            if (nullptr == pNextNode)
            {
                return false;
            }
            pNode = pNextNode;
        }
        return pNode->m_isEnding;
    }
    
    int DFS(CDictTree *tree, vector<string> *vec, string str)
    {
        if (tree != this)
        {
            str.append(1, tree->m_bChar);
            if (tree->m_isEnding)
            {
                vec->push_back(str);    
            }
        }
        
        CDictTree *pNextNode;
        for (int i = 0; i < gc_visibleCharNum; i++)
        {
            pNextNode = tree->m_pNext[i];
            if (nullptr != pNextNode)
            {
                DFS(pNextNode, vec, str);    
            }
        }
        
        return 1;
    }
};
int main()
{
    string strs[10]={"he", "0him", "hello", "qian_xi", "We are famliy", "alibaba", "xutaiping", "CharlesKevin", "visiblechar", "!@#$%^&"};
    vector<string> vecStr(strs,strs + 10);
    
    // Build Tree
    CDictTree tree;
    for (vector<string>::iterator it = vecStr.begin(); it != vecStr.end(); it++)
    {
        tree.insert(*it);    
    }

    // Search
    for (vector<string>::iterator it = vecStr.begin(); it != vecStr.end(); it++)
    {
        printf("Search %s : %d\n", (*it).c_str(), tree.search(*it));    
    }
    
    printf("Search Not Exist: %d\n", tree.search("What are u nong sha ne.."));  
    
    // DFS
    vector<string> vecOrderStr;
    tree.DFS(&tree, &vecOrderStr, "CharlesTest--");
    
    for (vector<string>::iterator it = vecOrderStr.begin(); it != vecOrderStr.end(); it++)
    {
        cout<<*it<<endl;   
    }

    return 0;
}

运行效果

关注 “CHARLESTEST-”的输出即可

Search he : 1
Search 0him : 1
Search hello : 1
Search qian_xi : 1
Search We are famliy : 1
Search alibaba : 1
Search xutaiping : 1
Search CharlesKevin : 1
Search visiblechar : 1
Search !@#$%^& : 1
Search Not Exist: 0
CharlesTest--!@#$%^&
CharlesTest--0him
CharlesTest--CharlesKevin
CharlesTest--We are famliy
CharlesTest--alibaba
CharlesTest--he
CharlesTest--hello
CharlesTest--qian_xi
CharlesTest--visiblechar
CharlesTest--xutaiping
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐徐太平KevinCharles

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值