程序可以输出自身的副本吗

问题描述 投票:0回答:12

我认为这可能是一个经典问题,但我不知道答案。程序可以输出自身的副本吗?如果可以,是否有一个短程序可以做到这一点?

我不接受“空程序”作为答案,并且我不接受可以访问自己的源代码的程序。相反,我在想这样的事情:

int main(int argc, char** argv){ printf("int main(argc, char** argv){ printf...

但我不知道如何继续...

algorithm compression complexity-theory quine
12个回答
38
投票

它被称为 quine,并且有一个网站 收集它们


18
投票

是的。可以复制自身的程序称为“quine”。

大多数奎因的基本思想是:

  1. 您编写的代码接受字符串文字

    s
    并打印它,同时用 s 本身的值替换 s 中特殊子字符串
    foo
    的出现(或
    the
    出现)。

  2. 您获取了到目前为止程序的整个源代码,并将其用作

    s
    的定义。但您从字符串排除了
    s的定义,而是用foo替换它。

这就是总体思路。剩下的就是字符串格式化细节,真的。


6
投票

这被称为奎因

quine 是一种计算机程序,它不接受任何输入,并生成自己的源代码的副本作为其唯一的输出。可计算性理论和计算机科学文献中这些程序的标准术语是自复制程序、自复制程序和自复制程序。

当执行环境被视为一个函数时,quine 是执行环境的一个不动点。作为克莱恩递归定理的直接结果,奎因在任何图灵完备的编程语言中都是可能的。为了娱乐,程序员有时会尝试用任何给定的编程语言开发尽可能短的 quine。

来源:维基百科


4
投票

这确实是一个经典问题!

除了存在特定的quines之外,可计算性理论的一个重要结果是,对于您可能想要计算的任何函数,都存在一个“知道自己的程序文本”的程序,即如果需要的话可以打印自己。该定理称为 克莱恩第二递归定理


3
投票

是的。这是我大约 20 年前编写的一个 C 程序,它可以实现这一点。

http://womencht.reocities.com/Athens/8994/repeat.html


1
投票

如果你写一个奎因,请注意副本不会无限地写出自己的副本并最终接管世界。


1
投票

在 Jon Skeet 发明的语言中,以下运算符打印“Hello, world! ”.

h

我可以对这种语言进行修改,以便以下程序打印“Hello, world! ”:

Hello, world!

这就是打印自身的程序。

哦,虽然它有精确正确的数学定义,但你觉得有些奇怪吗?那是你的问题。 “我不接受……”哈!数学确实接受,而且她是我侍奉的情妇,所以我发布这个答案。


1
投票
我假设您允许解释语言。 (在某种程度上,所有语言都是解释的。)有人编写了解释器,如果您正在编写它,您可以向其中添加您喜欢的任何内置函数,例如 (lispy) 函数

(foo)

,除了打印“
(foo)
”。

或者你可以添加更复杂的宏类型函数

(printMeAndMyArgs ...)

所以关键在于如何定义问题。


0
投票
Michael Sipser 的《计算理论导论》在其中一章中解释了如何构建 quine。我最近根据这个想法编写了一个 Java 程序并将其发布在:

http://bornagainprogrammer.net/2009/11/07/hello-world-from-the-tm-self/

我建议您找到那本书并尝试用您最喜欢的语言自己实现该程序。那本书里还有很多其他有趣的定理。

-基兰


0
投票
// save it as file.cpp #include <iostream> #include <cstdlib> using namespace std; int main() { system("cat file.cpp"); return 0; }
    

0
投票
你可以使用这个代码

file = open("temp1.py", "r") try: temp_python = open("temp1.py", "w") except FileNotFoundError: temp_python = open("temp1.py", "w") for i in file: temp_python.writelines(i) // note this is python code // name the file as temp1.py


-1
投票
在 Java 中这是可能的,但有一些限制。

我用java编写了一个简单的代码,它可以自行打印。 您可以使用 C/C++ 的文字来使用相同的程序。您可以在该程序中添加任何您想要的内容,它会完全打印出来。

条件

  1. Java 文件不应位于任何包内

  2. 文件夹结构不应包含任何名称中带有空格的文件夹

  3. 编译目标应该是默认的或java文件所在的同一文件夹

    import java.io.FileInputStream; import java.net.URL; public class PrintYourself { public static void main(String[] args) { // TODO Auto-generated method stub URL location = PrintYourself.class.getProtectionDomain().getCodeSource().getLocation(); String path=location.getFile(); path=path.replace("/bin", "/src"); System.out.println(path); try{ FileInputStream st=new FileInputStream(path+"PrintYourself.java"); int i=0; while((i=st.read())!=-1){ System.out.print((char)i); } st.close(); } catch(Exception e){ System.out.println(e); } } }
    
    
© www.soinside.com 2019 - 2024. All rights reserved.