3

好吧,这真的不像是一个 C 问题那样是一个 Fizzbuzz 问题。

我在 C 中编写了一些简单的代码,用于根据需要打印出 fizzbuzz。

#include <stdio.h>

int main(void)
{
    int n = 30;
    int i;
    for (i = 1; i<=n; i++)
        printf("%s\n", (i % 15) == 0 ? "fizzbuzz" : (i % 5) == 0 ? "buzz" : (i % 3) == 0 ? "fizz" : i);
}

现在,最后一个 else 语句显然不起作用,因为 printf 接受一个字符串,而 'i' 是一个 int。我的问题是,我可以应用任何类型的转换来将“i”转换为字符串吗?

编辑:我应该提一下,我真正要问的是这个 fizzbuzz 测试是否可以使用单个打印语句来完成。除了好奇它是否可以完成之外,没有什么特别的原因我希望它是一个单一的打印语句。

EDIT2:问题已回答,这是我的实现:

#include <stdio.h>

int main(void)
{
    int i, n=30;        
    for (i = 1; i<=n; i++)
        printf((!(i%3) || !(i%5)) ? "%s\n" : "%d\n", !(i % 15) ? "fizzbuzz" : !(i % 5) ? "buzz" : !(i % 3) ? "fizz" : i);
}

http://codepad.org/DN7yBW99

4

4 回答 4

6

您尝试将所有逻辑放入printf调用中的方式使自己走投无路。最好先用“慢”的方式写出来,然后再寻找优化的方法。

for (i = 1; i <= n; i++) {
    if (i % 15 == 0)
        printf("fizzbuzz\n");
    else if (i % 5 == 0)
        printf("buzz\n");
    else if (i % 3 == 0)
        printf("fizz\n");
    else
        printf("%d\n", i);
}

附录:只用一个 printf 就可以了...

/* The following code is NOT recommended... */

int isFizz     = (i % 3 == 0      ) ? 1 : 0;
int isBuzz     = (i % 5 == 0      ) ? 1 : 0;
int isFizzBuzz = (isFizz && isBuzz) ? 1 : 0;

printf(
    (isFizz || isBuzz) ? "%s\n" : "%d\n",
    (
        isFizzBuzz ? "fizzbuzz" :
        isFizz     ? "fizz"     :
        isBuzz     ? "buzz"     :
        i
    )
);

http://codepad.org/LMr5WdIm

于 2015-04-11T07:23:05.363 回答
1

您可以通过将字符串文字作为格式 string传递,而不是使用 a%s来打印它们,从而将 args 简化为 printf。这利用了您知道or中没有%字符的事实。 保证将未使用的参数传递给 printf 是安全的"fizz""buzz"

要使源代码可读,请提取逻辑以从printf()自身中选择格式字符串,并将其存储在局部变量中。

#include <stdio.h>
int main(void)
{
    int n=30;        
    for (int i = 1; i<=n; i++) {
        int fizzy = (i % 3 == 0);
        int buzzy = (i % 5 == 0);

        const char *fmt = (fizzy && buzzy) ? "fizzbuzz\n" :
                          fizzy            ? "fizz\n"     :
                          buzzy            ? "buzz\n"     :
                          "%d\n";
        printf(fmt, i);
    }
}

有条件地确定要传递的参数然后进行一次调用,而不是用不同的参数写出相同的函数调用,这可能是一种很好的风格,并且可能会做出更好的 asm。如果您要传递的大多数 args 在不同的分支中都是相同的,这可能会很好,但这里不是这种情况。

通常最好只使用puts(隐式\n附加)或fputs打印不需要格式化的常量字符串。编译器知道这一点,甚至printf("Hello World!\n");printf("%s\n", "Hello World!")puts("Hello World!");在微不足道的情况下进行优化或优化。这个技巧意味着即使是固定字符串打印仍然会调用更昂贵的printf. (除了可读性之外,这是在这种特定情况下它不是一个好选择的具体原因之一。)

gcc 和clang 将其编译为 asm,其工作方式与源代码的工作方式相同printf总是获取两个参数(在rdirsi寄存器中),但有时格式字符串不使用第二个参数。更改-O3-Os使 gcc 使用div而不是乘法逆。

他们不会展开循环以匹配模数模式,或者将模数强度降低到向下计数器,或者像您在手写 asm FizzBu​​zz 中所做的任何聪明的事情。

有关编写紧凑 FizzBu​​zz 的迂回方法,请参阅CodeGolf.SE,其中%s%s%.d格式字符串有条件地获取空字符串。%.dis 指定精度为 0。非零整数正常打印,但打印0为空字符串。

于 2016-05-28T00:48:19.697 回答
0

编辑 对不起...我刚刚意识到这个线程是针对 C 解决方案的

递归实现:

vector<string> FizzBuzz::execute(int n) {

    if(n == 0)
        return vector<string>();

    auto push = n % 15 == 0 ? "fizzbuzz" :
                n % 3 == 0 ? "fizz" :
                n % 5 == 0 ? "buzz" :
                to_string(n);

    auto execution = execute(n-1);
    execution.push_back(push);
    return execution;
}
于 2017-07-02T16:20:42.467 回答
-1

按照建议,您可以使用itoa();. 下面的示例代码。

#include <stdio.h>
#include <stdlib.h>
int main(){
int num=23;
char snum[3];
itoa(num,snum,10);
printf("%s",snum);
}

itoa 用于将 an 转换int为 a string,参数如下。

itoa(int num, char string [], int base);

第一个参数是您要转换的数字。第二个参数是char要存储转换后的强字符串/数组。最后,第三个参数是要转换的数字所在的基数。

于 2015-04-11T07:01:29.387 回答