简体   繁体   English

如何让我的trie更有效率?

[英]How can I make my trie more efficient?

I'm working on a hacker rank problem and I believe my solution is correct. 我正在研究黑客等级问题,我相信我的解决方案是正确的。 However, most of my test cases are being timed out. 但是,我的大部分测试用例都已超时。 Could some one suggest how to improve the efficiency of my code? 有人可以建议如何提高我的代码的效率?

The important part of the code starts at the "Trie Class". 代码的重要部分始于“Trie Class”。

The exact question can be found here: https://www.hackerrank.com/challenges/contacts 确切的问题可以在这里找到: https//www.hackerrank.com/challenges/contacts

using System;
using System.Collections.Generic;
using System.IO;
class Solution
{
    static void Main(String[] args)
    {
        int N = Int32.Parse(Console.ReadLine());
        string[,] argList = new string[N, 2];
        for (int i = 0; i < N; i++)
        {
            string[] s = Console.ReadLine().Split();
            argList[i, 0] = s[0];
            argList[i, 1] = s[1];
        }

        Trie trie = new Trie();

        for (int i = 0; i < N; i++)
        {
            switch (argList[i, 0])
            {
                case "add":
                    trie.add(argList[i, 1]);
                    break;
                case "find":
                    Console.WriteLine(trie.find(argList[i, 1]));
                    break;
                default:
                    break;
            }
        }
    }
}

class Trie
{
    Trie[] trieArray = new Trie[26];
    private int findCount = 0;
    private bool data = false;
    private char name;

    public void add(string s)
    {
        s = s.ToLower();
        add(s, this);
    }

    private void add(string s, Trie t)
    {
        char first = Char.Parse(s.Substring(0, 1));
        int index = first - 'a';

        if(t.trieArray[index] == null)
        {
            t.trieArray[index] = new Trie();
            t.trieArray[index].name = first;
        }

        if (s.Length > 1)
        {
            add(s.Substring(1), t.trieArray[index]);
        }
        else
        {
            t.trieArray[index].data = true;
        }
    }

    public int find(string s)
    {
        int ans;
        s = s.ToLower();
        find(s, this);

        ans = findCount;
        findCount = 0;
        return ans;
    }

    private void find(string s, Trie t)
    {
        if (t == null)
        {
            return;
        }
        if (s.Length > 0)
        {
            char first = Char.Parse(s.Substring(0, 1));
            int index = first - 'a';
            find(s.Substring(1), t.trieArray[index]);
        }
        else
        {
            for(int i = 0; i < 26; i++)
            {
                if (t.trieArray[i] != null)
                {
                    find("", t.trieArray[i]);
                }
            }

            if (t.data == true)
            {
                findCount++;
            }
        }
    }

}

EDIT: I did some suggestions in the comments but realized that I can't replace s.Substring(1) with s[0]... because I actually need s[1..n]. 编辑:我在评论中做了一些建议,但意识到我不能用s [0]替换s.Substring(1)...因为我实际上需要s [1..n]。 AND s[0] returns a char so I'm going to need to do .ToString on it anyways. AND s [0]返回一个char,所以无论如何我都需要做.ToString。

Also, to add a little more information. 另外,添加更多信息。 The idea is that it needs to count ALL names after a prefix for example. 这个想法是它需要在前缀之后计算所有名称。

Input: "He"
Trie Contains:
"Hello"
"Help"
"Heart"
"Ha"
"No"
Output: 3

I could just post a solution here that gives you 40 points but i guess this wont be any fun. 我可以在这里发布一个解决方案,给你40分,但我想这不会有任何乐趣。

  • Make use of Enumerator<char> instead of any string operations 使用Enumerator <char>而不是任何字符串操作
  • Count while adding values 添加值时计数
  • any charachter minus 'a' makes a good arrayindex (gives you values between 0 and 25) 减去'a'的任何charachter都会产生一个很好的arrayindex(给你0到25之间的值)

在此输入图像描述

I think, this link must be very helpfull 我认为, 这个链接必须非常有用

There, you can find the good implementation of a trie data structure, but it's a java implementation. 在那里,你可以找到trie数据结构的良好实现,但它是一个java实现。 I implemented trie on c# with that great article one year ago, and i tried to find solution to an another hackerrank task too ) It was successful. 一年前我在c#上用一篇很棒的文章实现了trie,我试图找到另一个hackerrank任务的解决方案。它很成功。

在此输入图像描述

In my task, i had to a simply trie (i mean my alphabet equals 2) and only one method for adding new nodes: 在我的任务中,我只需要一个简单的trie(我的意思是我的字母表等于2)并且只有一种添加新节点的方法:

public class Trie
{
   //for integer representation in binary system 2^32
    public static readonly int MaxLengthOfBits = 32;
    //alphabet trie size
    public static readonly int N = 2;

    class Node
    {
        public Node[] next = new Node[Trie.N];
    }

    private Node _root;
}

public void AddValue(bool[] binaryNumber)
{
    _root = AddValue(_root, binaryNumber, 0);
}

private Node AddValue(Node node, bool[] val, int d)
{
    if (node == null) node = new Node();

    //if least sagnificient bit has been added
    //need return
    if (d == val.Length)
    {   
        return node;
    }

    // get 0 or 1 index of next array(length 2)
    int index = Convert.ToInt32(val[d]); 
    node.next[index] = AddValue(node.next[index], val, ++d);
    return node;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM