尝试 - 联系人 - Hackerrank

Posted

技术标签:

【中文标题】尝试 - 联系人 - Hackerrank【英文标题】:Tries - Contacts - Hackerrank 【发布时间】:2017-10-11 15:36:57 【问题描述】:

我目前正在尝试在hackerrank Tries - Contacts上解决这个挑战

而且我的算法仅对一个测试用例失败。测试用例 #1。任何人都可以分享我需要改变什么才能通过这个测试用例的任何见解。我正在使用包含其子节点哈希图的 TrieNode 类。我还存储了每个节点的大小,以了解它包含多少个单词。

测试用例#1如下:

add s 
add ss
add sss
add ssss
add sssss
find s
find ss
find sss
find ssss
find sssss
find ssssss

代码如下:

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution 

    TrieNode root;

    class TrieNode
        Map<Character, TrieNode> children = new HashMap<Character, TrieNode>();
        int size=0;
    

    public Solution()
        root = new TrieNode();
    

    public void addWord(String word)
        TrieNode current = root;
        for(int i=0;i<word.length();i++)
            char c = word.charAt(i);
            if(!current.children.containsKey(c))
                //create a new node
                TrieNode temp = new TrieNode();
                //add the word to the current node's children
                current.children.put(c, temp);
                current.size++;
                current = temp;
            
            else
                current.size++;
                current = current.children.get(c);
            
        
    

    public void prefixSearch(String letters)

        TrieNode current = root;
        boolean sequenceExists = true;

        for(int i=0; i<letters.length();i++)
            char c = letters.charAt(i);
            if(current.children.containsKey(c))
                if(i == letters.length()-1)
                    System.out.println(current.size);
                    break;
                
                else
                    current = current.children.get(c);
                
            
            else
                System.out.println(0);
                break;
            
        

    

    public static void main(String[] args) 
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        Solution sol = new Solution();
        for(int a0 = 0; a0 < n; a0++)
            String op = in.next();
            String contact = in.next();

            if(op.equals("add"))
                if(contact.length() >=1 && contact.length() <=21)
                sol.addWord(contact);
            
            else if(op.equals("find"))
                if(contact.length() >=1 && contact.length() <=21)
                sol.prefixSearch(contact);
            
            else
                //do nothing
            
        
    

【问题讨论】:

什么是测试用例 #1? 我会把它添加到他的问题中 有一瞬间我以为你被蟒蛇附身了。 当你尝试你提到的输入时会发生什么,应该发生什么? 是的,哈哈……这里的格式很糟糕 【参考方案1】:

当您向 Trie 添加单词时,您会增加所有节点的计数,最后一个除外。这是一种很常见且很难注意到的错误,称为一对一的错误https://en.wikipedia.org/wiki/Off-by-one_error

在 addWord 方法的末尾(循环之后)再次添加这一行:

current.size++;

您的代码通过了测试用例 0,因为当您查找诸如 hac-kerrank 之类的前缀时,您的代码中的这个特定错误不会出现,但在您查找完整单词时会出现包括 last 字符,例如 hackerranksssss

【讨论】:

感谢米洛·贝姆。我永远不会明白这一点。我还是不明白。让我尝试重新阅读您所写的内容并尝试消化它。然而,这就是问题所在。顺便说一句,很棒的收获。 寻找这些的策略是什么? 阅读我链接的***文章,一些示例实际上与您的情况非常相似。就像我写的那样,这种错误通常很难被注意到,因为它只出现在特定情况下,比如当你恰好碰到边界情况时。这就是为什么正确的测试在商业编程中很重要的原因。 太棒了。多谢。我已尽我所能为您提供更多积分,例如将答案标记为正确和投票。如果我错过了什么,请告诉我。谢谢。【参考方案2】:

我有这个解决方案,除了测试用例 0、1 和 5 之外,所有其他的都超时。这是我在 java 8 中的实现。我应该在哪里改进我的代码以通过所有测试用例

public class Contacts 
    static Map<String, String> contactMap = new HashMap<>();
    public static void main(String[] args) 
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();

        for(int a0 = 0; a0 < n; a0++)
            String op = in.next();
            String contact = in.next();
            if(op.equalsIgnoreCase("add")) 
                addOrFind(contact, op);
             else 
                addOrFind(contact, op);
            
        
    

    public static void addOrFind(String name, String type) 
        if(type.equalsIgnoreCase("add")) 
            contactMap.put(name, name);
         else 
            long count = contactMap.entrySet().stream()
                    .filter(p->p.getKey().contains(name)).count();
            System.out.println(count);
        

    



【讨论】:

你弄明白了吗? @Spindoctor 我已经阅读了一些使用 Trie 的解决方案,但没有使用我当前的实现【参考方案3】:

如果您要结帐:enter link description here

并且还使用他们的测试用例: 4 添加黑客 添加黑客等级 找到hac 找哈克

它会编译。

//来自他的网站https://github.com/RodneyShag/HackerRank_solutions/blob/master/Data%20Structures/Trie/Contacts/Solution.java

import java.util.Scanner;
import java.util.HashMap;
public class Solution 
    public static void main(String[] args) 
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        Trie trie = new Trie();
        for (int i = 0; i < n; i++) 
            String operation = scan.next();
            String contact   = scan.next();
            if (operation.equals("add")) 
                trie.add(contact);
             else if (operation.equals("find")) 
                System.out.println(trie.find(contact));
            
        
        scan.close();
    

/* Based loosely on tutorial video in this problem */
class TrieNode 
    private HashMap<Character, TrieNode> children = new HashMap<>();
    public int size = 0; // this was the main trick to decrease runtime to pass tests.
    public void putChildIfAbsent(char ch) 
        children.putIfAbsent(ch, new TrieNode());
    
    public TrieNode getChild(char ch) 
        return children.get(ch);
    

class Trie 
    TrieNode root = new TrieNode();
    Trie() // default constructor

    Trie(String[] words) 
        for (String word : words) 
            add(word);
        
    

    public void add(String str) 
        TrieNode curr = root;
        for (int i = 0; i < str.length(); i++) 
            Character ch = str.charAt(i);
            curr.putChildIfAbsent(ch);
            curr = curr.getChild(ch);
            curr.size++;
        
    

    public int find(String prefix) 
        TrieNode curr = root;

        /* Traverse down tree to end of our prefix */
        for (int i = 0; i < prefix.length(); i++) 
            Character ch = prefix.charAt(i);
            curr = curr.getChild(ch);
            if (curr == null) 
                return 0;
            
        
        return curr.size;
    

【讨论】:

以上是关于尝试 - 联系人 - Hackerrank的主要内容,如果未能解决你的问题,请参考以下文章

尝试 - 联系人 - Hackerrank

尝试在 mailchimp 中添加联系人时出现错误 400

尝试访问 android 应用程序中的联系人不断崩溃

Android:我正在尝试根据他们的显示名称搜索联系人

尝试在用户和用户联系人(Stackmob)之间建立一对多关系时应用程序被击中

UCWA 2.0 尝试添加转发联系人但获取 ParameterValidationFailure