【发布时间】:2014-03-07 07:04:55
【问题描述】:
当我查看CharMatcher 的实现并注意到一个字段WHITESPACE_MULTIPLIER=1682554634 时,我将此值设置为1582554634,运行测试用例CharMatcherTest#testWhitespaceBreakingWhitespaceSubset,当然它失败了。
之后我将testWhitespaceBreakingWhitespaceSubset改为只调用WHITESPACE.apply((char)c)不带assert,在WHITESPACE.matches的方法中打印索引
int index=(WHITESPACE_MULTIPLIER * c) >>> WHITESPACE_SHIFT)
将WHITESPACE_MULTIPLIER从1682554634更改为1582554634后终于发现索引发生冲突
毫无疑问,1682554634 设计得很好,我的问题是我怎样才能推断出这个“幻数”?`
在Martin Grajcar's proposal 上,我尝试如下编写“幻数生成器”并工作:
char[] charsReq = WHITESPACE_TABLE.toCharArray();
Arrays.sort(charsReq);
OUTER:
for (int WHITESPACE_MULTIPLIER_WANTTED = 1682553701; WHITESPACE_MULTIPLIER_WANTTED <= 1682554834; WHITESPACE_MULTIPLIER_WANTTED++) {
int matchCnt = 0;
for (int c = 0; c <= Character.MAX_VALUE; c++) {
int position = Arrays.binarySearch(charsReq, (char) c);
char index = WHITESPACE_TABLE.charAt((WHITESPACE_MULTIPLIER_WANTTED * c) >>> WHITESPACE_SHIFT);
if (position >= 0 && index == c) {
matchCnt++;
} else if (position < 0 && index != c) {
matchCnt++;
} else {
continue OUTER;
}
}
// all valid
if ((matchCnt - 1) == (int) (Character.MAX_VALUE)) {
System.out.println(WHITESPACE_MULTIPLIER_WANTTED);
}
}
如果更改了WHITESPACE_TABLE中的字符序列(交换\u2001 \u2002位置),算法没有解决方案(将循环结束条件更改为Integer.MAX_VALUE)。
因为 IntMath.gcd 实现是指 http://en.wikipedia.org/wiki/Binary_GCD_algorithm
我的问题是:我在哪里可以找到 CharMatcher.WHITESPACE.match 实现的材料?
【问题讨论】:
-
我不确定你在问什么。是否仍不清楚该表是如何生成的?你的代码对于我所做的来说有点太复杂了。
-
CharMatcher.WHITESPACE.match实现想要的素材。代码是生成非冲突索引随机数
-
@Marichyasana:OP 想知道,如何
WHITESPACE_MULTIPLIER在第 1357 行已生成,这是 AFAIK 不在 Guava 中。 -
@Marichyasana 感谢您提供信息