程序可以输出自己的副本

时间:2009-09-25 20:45:02

标签: algorithm compression complexity-theory quine

我认为这可能是一个经典问题,但我不知道答案。程序是否可以输出自身的副本,如果有的话,是否有一个简短的程序来执行此操作?

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

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

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

11 个答案:

答案 0 :(得分:36)

它被称为quine,并且有一个网站that collects them

答案 1 :(得分:14)

大多数quines的基本理念是:

  1. 您编写的代码采用字符串文字s并打印出来,同时替换特殊子字符串 foo 的出现次数(或 出现次数)在ss本身的值。

  2. 到目前为止,您已获取该程序的完整源代码,并将其用作s的定义。但您从字符串中排除 s 的定义,而是将其替换为 foo

  3. 嗯,这是一般的想法。其余的是字符串格式化细节,真的。

答案 2 :(得分:5)

这称为Quine

  

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

     

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

来源:维基百科

答案 3 :(得分:4)

这确实是一个经典问题!

除了特定的quines之外,可计算性理论的一个重要结果是,对于你可能想要计算的任何函数,存在一个“知道自己的程序文本”的程序。 ,即如果需要可以打印自己。这个定理叫做Kleene's second recursion theorem

答案 4 :(得分:3)

是。这是我20年前写的一个C程序。

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

答案 5 :(得分:1)

如果你写一个quine,请注意副本不会无限制地写出自己的副本,最终会占领世界。

答案 6 :(得分:1)

language invented by Jon Skeet中,以下操作符打印“Hello,world!\ n”。

h

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

Hello, world!

这就是打印自己的程序。

哦,你觉得它有点奇怪,虽然它有一个精确和正确的数学定义?那是你的问题。 “我不会接受......”哈!数学确实接受了,她是我服务的情妇,所以我发布了这个答案。

答案 7 :(得分:1)

我假设您允许解释语言。 (在某种程度上,所有语言都被解释。)有人编写解释器,如果你正在编写它,你可以添加任何你喜欢的内置函数,例如(lispy)函数(foo)除了打印“(foo)”之外没什么。

或者您可以添加更复杂的宏类型函数(printMeAndMyArgs ...)

所以诀窍在于你如何定义问题。

答案 8 :(得分:0)

Michael Pipser的“计算理论导论”在其中一章中解释了如何构建一个quine。我最近根据这个想法编写了一个Java程序,并将其发布在:http://bornagainprogrammer.net/2009/11/07/hello-world-from-the-tm-self/

我建议你掌握那本书,并尝试用自己喜欢的语言自己实施该程序。那本书中还有很多其他有趣的定理。

-kiran

答案 9 :(得分:0)

// save it as file.cpp

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
    system("cat file.cpp"); 
    return 0;
}

答案 10 :(得分:0)

可以在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);
            }
    
        }
    }