簡體   English   中英

破解編碼面試字謎:獨特的字符變量檢查

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

我有一個關於破解編碼面試中的“字謎”問題的具體問題。 在我下面的代碼中,方法 'anagram' 是書中的方法,anagram2 是我自己的邏輯(缺少唯一的字符跟蹤器和總數跟蹤器。)由於我們確保兩個字符串的長度相等,我假設每個字符的計數是我們需要跟蹤的全部。 對於我所做的輸入,我看到了與我的測試用例相同的答案。 我想了解我在這里缺少哪些測試用例來保證“字謎”中的附加邏輯。 任何幫助表示贊賞!

問題定義 - 編寫一個方法來確定兩個字符串是否是字謎。

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"));
    }
}

如果您不確定並且您有參考實現,只需嘗試對有限域進行詳盡的搜索即可。 我使用數字的字符串表示進行測試。

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");
}

您的實現始終返回與參考實現相同的結果。 我認為可以肯定的是,如果在這個范圍內沒有反例,其他地方也不會有。

順便一提。 兩種實現的速度幾乎完全相同(至少在我的測試中)

是的,你的方法是正確的。 我不得不同意anagrams方法有很多冗余。 這是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;
}

這是一段代碼,您可以用它來測試您的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);
        }
    }
}

要測試您的代碼,只需調用

test(10000, 3);

取決於你想用多長的字符串運行多少個測試用例。 不要在長字符串上運行它,因為創建字謎對的機會很小。 長度3似乎合理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM