无法理解这段代码?

时间:2017-01-02 16:51:00

标签: c++ function comma-operator

任何人都可以帮助我理解以下代码: -

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.在字符串后使用[]运算符 实际上是整个代码。

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 % 10n的低位十进制数字。我们使用它作为字符串文字的索引(它只是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;

让我给你一些基础知识。

  1. 在c ++中
  2. 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;
}

我不知道他试图使用哪些字符,但在挑战网站上没有工作。