任何人都可以帮助我理解以下代码: -
ghci> :set -XDeriveFunctor
ghci> newtype Pair a = Pair (a,a) deriving (Show,Functor)
ghci> fmap reverse (Pair ("aA","bB"))
Pair ("Aa","Bb")
我在codefights.com的挑战中发现了这段代码,https://codefights.com/challenge/v5Zg8trjoun3PTxrZ/solutions/Aj3ppbhSShixt4nBi
这是一个计算数字中孔数的解决方案 例如
int r, countIt(int n) {
while (r += " 2 "[n % 10] & 3, n /= 10);
return r;
}
我无法理解以下事项:
1.此代码的逻辑
2.逗号(,)运算符用于返回数据类型的函数
3.在字符串后使用[]运算符
实际上是整个代码。
答案 0 :(得分:9)
这是某种obfuscated C contest提交的内容吗?或code golf?
首先,奇怪的声明。它只是将两个不相关的声明组合在一行上。就像
一样int x, y;
相当于
int x;
int y;
您的代码等同于
int r;
int countIt(int n) {...}
它有一点鲜为人知,谢天谢地,你可以做的很少使用C语法的怪癖。
如果以这种方式书写,循环会变得更清晰:
do {
r += " 2 "[n % 10] & 3;
n /= 10;
} while (n);
它基本上遍历n
的十进制表示中的数字。
现在是r += " 2 "[n % 10] & 3;
的一部分。 n % 10
是n
的低位十进制数字。我们使用它作为字符串文字的索引(它只是char
s的数组),然后提取字符的ASCII码的两个低位,并丢弃其余的。我很确定,在您复制此代码的原始程序中,该文字中的字符不是空格,而是以某种方式选择某些不可打印的字符,使得它们的ASCII代码的两个低位给出正确的数量"孔"在相应的数字。 2
字符是红色鲱鱼 - 它位于第12位,但实际上只使用字符0到9。
换句话说,这部分可以用这种方式写得更清楚:
static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1};
int digit = n % 10;
r += numHoles[digit];
放在一起,我们有:
int countIt(int n) {
// number of holes in digit 0 1 2 3 4 5 6 7 8 9
static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1};
int r = 0;
do {
int digit = n % 10;
r += numHoles[digit];
n /= 10;
} while (n);
return r;
};
答案 1 :(得分:1)
我查了你提供的链接。在仔细观察代码后,我得出了以下结论。
int r, countIt(int n) {.....}
相当于写作
int r;
int countIt(int n){.....}
现在
while (r += " 2 "[n % 10] & 3, n /= 10);
相当于:
do{
r += " 2 "[n % 10] & 3;
n/=10;
}while(n);
现在是代码的逻辑部分
r += " 2 "[n % 10] & 3;
让我给你一些基础知识。
cout<<"abcde"[2];
会给你输出
c
现在,如果您仔细观察您提供的链接中的代码 它是这样的:
r += " 2 "[n % 10] & 3;
只是
r += "TAB,SPACE,SPACE,SPACE,SPACE,SPACE,TAB,SPACE,2,TAB"[n % 10] & 3;
现在是时候解释这段代码如何计算漏洞的数量了。 TAB的ASCII值为9,二进制等效值为1001。 SPACE的ASCII值为32,二进制等效值为100000。
如此有点明智和TAB将导致
1001 & 0011 = 0001 which is 1
有点明智而且空间与3将导致
100000 & 000011 = 000000 which is 0
将TAB替换为1,将SPACE替换为0,因此写作
do{
r += "1000001021"[n % 10] & 3;
n/=10;
}while(n);
n%10是n的低位十进制数字。我们将其用作字符串文字的索引,其中包含有关该低位十进制数字中有多少个孔的信息,然后将其添加到结果r中。
答案 2 :(得分:0)
在浏览器中使用特殊字符可能是一个问题,从Ascii Table我们可以使用八进制结束的所有字符,从0到2或4到6,使用这两个字来知道该数字有多少个洞( testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
与% 3
相同,a和最后2位相同。
使用ascii字符的一个解决方案是:
% 0b11
而不是&#34; 0&#34;到&#34; 2&#34;,我可以使用这样的东西:
int countIt(int n) {
int r;
while (r += "1000101021"[n % 10] & 3, n /= 10);
return r;
}
我不知道他试图使用哪些字符,但在挑战网站上没有工作。