什么是Quines?有什么特定的用途吗?

20
我遇到了一个术语 - Quine(也称为自我复制程序)。只是想更多地了解它。如何编写Quine?它们是否被用于任何地方,还是仅作为娱乐练习?
我从Python开始,可能会尝试在Python中编写一个Quine。有什么建议吗?
10个回答

30

Quines在实际意义上是没有用处的,但它们是一个很好的练习,可以帮助你更好地了解一门语言。

这里有一个非常简洁的Python Quine示例:

a='a=%r;print a%%a';print a%a

5
我看到的最简短版本,点个赞。 - MitMaro
1
它也可以轻松转换为Python 3.x:a='a=%r;print(a%%a)';print(a%a) - dan04
3
使用.format()方法替代已被弃用的%符号:a='a={};print(a.format(repr(a)))';print(a.format(repr(a))) - Aprillion

19
作为最基本的要求,quines是一种能够将自身源代码作为输出的程序。它们是构建哥德尔不完备性定理的必要步骤。
至于这是否构成实际应用,我不做评论。

11

一个Quine是一种计算机程序,它的唯一输出是复制其自身源代码。

我还没有看到Quine的实际用途,但我相信某个地方会有用处。


Python示例(在这里找到

print (lambda s:s+`s`+')')("print (lambda s:s+`s`+')')(")

在这里找到的C语言示例 (点击此处)

#include <stdio.h>
 
int main(int argc, char** argv)
{
/* This macro B will expand to its argument, followed by a printf
 command that prints the macro invocation as a literal string */
#define B(x) x; printf("  B(" #x ")\n");
 
/* This macro A will expand to a printf command that prints the
 macro invocation, followed by the macro argument itself. */
#define A(x) printf("  A(" #x ")\n"); x;
 
/* Now we call B on the text of the program
 up to this point. It will execute the command, and then cause
 itself to be printed. */
  B(printf("#include <stdio.h>\n\nint main(int argc, char** argv)\n{\n/*
    This macro B will expand to its argument, followed by a printf\n
    command that prints the macro invocation as a literal string
    */\n#define B(x) x; printf(\"  B(\" #x \")\\n\");\n\n/* This macro
    A will expand to a printf command that prints the\n
    macro invocation, followed by the macro argument itself. */\n#define A(x)
    printf(\"  A(\" #x \")\\n\"); x;\n\n/* Now we call B on the text
    of the program\n up to this point. It will execute the command,
    and then cause\n itself to be printed. */\n"))
  A(printf("/* Lastly, we call A on a command to print the remainder
    of the program;\n it will cause itself to be printed, and then
    execute the command. */\n}\n"))
/* Lastly, we call A on a command to print the remainder of the program;
 it will cause itself to be printed, and then execute the command. */
}

9

正如其他人所解释的那样,quines是能够复制自身的程序。

关于应用方面,如果你认为DNA编码了解释和复制自身的逻辑-答案非常简单,没有quines的概念,我们就不存在,并且永远无法创造出人工(自我复制)生命。


6

这是我最喜欢的C语言示例

char*p="char*p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}

从中我学到了两件事:

  1. 空格并非必须,不过有助于提高可读性
  2. prinftf 函数确实功能强大

4
我无法提供任何数据来证明编写一个Quine或两个能够扩展我的思维或者使我成为更好的程序员。但至少在前几次尝试时,这是一件有趣的事情。无论如何,你问如何编写Quine,我可以指向一些写得很好的参考文献:
Craig Kaplan撰写了一篇有趣的论文,其中描述了如何实际产生Quine:
- 寻找自我描述代码 - 本报告探讨了编写自我描述程序的问题:当运行时,程序会将自己作为输出产生。从自我引用的角度考虑了解决方案的需求,本报告从最初无法正常工作的程序开始,逐步向解决方案接近的程序发展,直到能够正常工作的自我描述程序。然后,它稍微退后一步,并展示了一些程序看起来似乎作弊,但仍符合自我描述程序的定义,建议对该定义进行改进。在每个步骤中,报告都解释了给定的程序如何演示计算机编程和自我引用之间的微妙关系。

您可能会发现David Madore的"Quines(自复制程序)"有趣可读。

最后,如果您想查看实现,请查看Quine Page,在那里您可以找到各种语言的quines和其他相关内容。


2

Quine是用于什么的?编程练习和病毒。

病毒需要以某种方式复制 - 其中一种方式是将其变成Quine。假设一个假想的杀毒软件会标记任何将其自己的二进制读入内存(以传递给预期受害者)的过程; 绕过这个问题的方法是让它输出自己。

请注意,机器码中的Quine不需要编译。


机器码中的奎因程序不需要编译。 - Blorgbeard

1

这是一个用Python编写的程序(很丑陋;我只是为了尝试而编写它)。当时甚至不知道这被称为quine。

def e(s): print s[:42]+s[42:].replace('#','"'); print 'e("""'+s+'""")'
e("""def e(s): print s[:42]+s[42:].replace('#','"'); print 'e(###'+s+'###)'""")

哦,回答你的另一个问题:Quine 完全没有用。


1

我在1979年用Fortran编写了我的第一个奎因。最近,我突发奇想,想探讨一下PHP中的奎因,并考虑发布与原帖相同的问题,但我首先查看了问答数据库以确认是否已有解决方案。无论如何,为了后人着想,这是我的PHP(cli)奎因代码。如果有更短的变体,我会很感兴趣的。:-)

<?php $x='<?php $x=0;echo strtr( $x, array(chr(39).$x.chr(39)));';echo strtr( $x, array(chr(39).$x.chr(39)));

109字节,但最后一个CR被切掉了。这还不包括“作弊”的部分:

<?php readfile( __FILE__);

而这个QuineProgram维基引用了一个更短的:

<?php printf($a='<?php printf($a=%c%s%c,39,$a,39);',39,$a,39);

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接