[英]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.