简体   繁体   English

破解编码面试字谜:独特的字符变量检查

[英]Cracking the coding interview anagram: unique character variable check

I have a specific question regarding the "Anagram" problem in Cracking the coding interview.我有一个关于破解编码面试中的“字谜”问题的具体问题。 In my code below, the method 'anagram' is the one which is from the book and anagram2 is my own logic(which is missing the unique char tracker and total number tracker.) Since we are ensuring that both strings are of equal length, I assumed count of each char is all we needed to keep track of.在我下面的代码中,方法 'anagram' 是书中的方法,anagram2 是我自己的逻辑(缺少唯一的字符跟踪器和总数跟踪器。)由于我们确保两个字符串的长度相等,我假设每个字符的计数是我们需要跟踪的全部。 For the inputs that I have made, I see identical answers for my test cases.对于我所做的输入,我看到了与我的测试用例相同的答案。 I want to understand what testcases I am missing here that warrants the additional logic in 'anagram'.我想了解我在这里缺少哪些测试用例来保证“字谜”中的附加逻辑。 Any help is appreciated!任何帮助表示赞赏!

Problem definition - Write a method to decide if two strings are anagrams or not.问题定义 - 编写一个方法来确定两个字符串是否是字谜。

public class anagram {
    public static boolean anagram(String s, String t) {

         if (s.length() != t.length()) return false;
         int[] letters = new int[256];
         int num_unique_chars = 0;
         int num_completed_t = 0;
         char[] s_array = s.toCharArray();
         for (char c : s_array) { // count number of each char in s.
             if (letters[c] == 0) ++num_unique_chars;
             ++letters[c];
             }
         for (int i = 0; i < t.length(); ++i) {
             int c = (int) t.charAt(i);
             if (letters[c] == 0) { // Found more of char c in t than in s.
                 return false;
                 }
             --letters[c];
             if (letters[c] == 0) {
                 ++num_completed_t;
                 if (num_completed_t == num_unique_chars) {
                     // it’s a match if t has been processed completely
                     return i == t.length() - 1;
                     }
                 }
             }
         return false;
    }
    public static boolean anagram2(String s, String t) {
        if (s.length() != t.length()) return false;
        int[] letters = new int[256];
        char[] s_array = s.toCharArray();
        for (char c : s_array) { // count number of each char in s.
            ++letters[c];
        }
        for (int i = 0; i < t.length(); ++i) {
            int c = (int) t.charAt(i);
            if (letters[c] == 0) { // Found more of char c in t than in s.
                return false;
            }
            --letters[c];
            if (letters[c] == 0) {
                if (i == t.length() - 1) {
                    // it’s a match if t has been processed completely
                    return i == t.length() - 1;
                }
            }
        }
        return false;
    }

    public static void main(String args[]) {
        System.out.println(anagram("onex","noey"));
        System.out.println(anagram("onex","noey"));
        System.out.println(anagram("onen","noen"));
        System.out.println(anagram("abcde", "abedc"));
        System.out.println(anagram("ababab", "baaabb"));
        System.out.println(anagram("aaaa", "aaaa"));
        System.out.println(anagram2("onen", "noen"));
        System.out.println(anagram2("abcde", "abedc"));
        System.out.println(anagram2("ababab", "baaabb"));
        System.out.println(anagram2("aaaa", "aaaa"));
    }
}

If you are not sure and you have a reference implementation, simply try an exhausting search for a limited domain.如果您不确定并且您有参考实现,只需尝试对有限域进行详尽的搜索即可。 I used the String representation of numbers for testing.我使用数字的字符串表示进行测试。

private static final int LIMIT = 9999;

public static final void main(final String[] args) {
    for (int i = 0; LIMIT > i; i++) {
        for (int i2 = 0; LIMIT > i2; i2++) {
            final String s = "" + i;
            final String t = "" + i2;
            if (anagram2(s, t) != anagram(s, t)) {
                System.err.println("s: " + s + "  t:" + t);
            }
        }
    }
    System.err.println("end");
}

Your implementation always returns the same result, as the reference implementation.您的实现始终返回与参考实现相同的结果。 I think it is sure to assume if there is no counter example in this range, there will be none elsewhere too.我认为可以肯定的是,如果在这个范围内没有反例,其他地方也不会有。

by the way.顺便一提。 Both implementations are of nearly exact the same speed (at least in my test)两种实现的速度几乎完全相同(至少在我的测试中)

Yes, your method is correct.是的,你的方法是正确的。 I have to agree that the method anagrams has a lot of redundancy.我不得不同意anagrams方法有很多冗余。 Here's even simpler version for anagrams2 :这是anagrams2的更简单版本:

public static boolean anagram2(String s, String t) {
    if (s.length() != t.length()) return false;
    int[] letters = new int[256];
    char[] s_array = s.toCharArray();
    for (char c : s_array)
        ++letters[c];
    for (int i = 0; i < t.length(); ++i) {
        int c = (int) t.charAt(i);
        if (letters[c] == 0)
            return false;
        --letters[c];
    }
    return true;
}

Here's a piece a code with which you can test your anagram2 versions:这是一段代码,您可以用它来测试您的anagram2版本:

static Random r = new Random();
public static String generateString(int n) {
    StringBuilder sb = new StringBuilder();
    for (int i =  0; i < n; ++i)
        sb.append((char) (r.nextInt(3) + 'a'));
    return sb.toString();
}

static void test(int cases, int stringLength) {
    for (int i = 0; i < cases; ++i) {
        String s = generateString(stringLength);
        String t = generateString(stringLength);
        boolean ans1 = anagram(s, t);
        boolean ans2 = anagram2(s, t);

        if (ans1 != ans2) {
            System.out.printf("TESTCASE %d: FAIL\n", i+1);
            System.out.printf("%b %b\n", ans1, ans2);
            System.out.printf("%s %s\n", s, t);
            return;
        } else {
            System.out.printf("TESTCASE %8d: OK\n", i + 1);
        }
    }
}

To test your code just call要测试您的代码,只需调用

test(10000, 3);

depending on how many testcase you want to run with how long strings.取决于你想用多长的字符串运行多少个测试用例。 Don't run it on long strings since the chance of create a anagram pair is small.不要在长字符串上运行它,因为创建字谜对的机会很小。 Length 3 seems reasonable.长度3似乎合理。

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

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