【问题标题】:Can a program output a copy of itself程序可以输出自身的副本吗
【发布时间】:2009-09-25 20:45:01
【问题描述】:

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

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

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

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

【问题讨论】:

  • Ragnarius - 您可能想阅读 Douglas Hoffstader 的“哥德尔、埃舍尔和巴赫”。他的书描述了其他形式的算法以及与您对 quines 的兴趣相似的算法的性质。我会考虑这本与您的问题有很大关系的“经典”计算机科学文本。
  • 试试这个搜索:stackoverflow.com/search?q=quine

标签: algorithm compression complexity-theory quine


【解决方案1】:

它叫quine,有一个网站that collects them

【解决方案2】:

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

大多数quines的基本思想是:

  1. 您编写的代码采用字符串文字 s 并打印它,同时替换 @ 中特殊子字符串 foo 的出现(或 出现) 987654322@ 由s 本身的值。

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

这是一般的想法。剩下的就是字符串格式化细节了,真的。

【讨论】:

    【解决方案3】:

    这叫做Quine

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

    当执行环境被视为一个函数时,quine 是执行环境的一个固定点。 Quines 在任何图灵完备的编程语言中都是可能的,这是 Kleene 递归定理的直接结果。为了消遣,程序员有时会尝试在任何给定的编程语言中开发尽可能短的 quine。

    来源:维基百科

    【讨论】:

      【解决方案4】:

      这确实是个经典问题!

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 那是一个非常简洁的小程序!
        【解决方案6】:

        如果你写了一个 quine,请注意副本不要无限地写自己的副本并最终接管世界。

        【讨论】:

        • 这就是写副本和执行副本的区别。
        • 如果副本开始自我复制,它们将不得不被执行。
        • 直到这一刻,我才将 quine 等同于 RNA。请问哪里有奎因疫苗!拯救自己,人们!
        【解决方案7】:

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

        h
        

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

        Hello, world!
        

        这就是打印自己的程序。

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

        【讨论】:

        • 是的,当我想到它时,我还可以想象运算符 h 实际输出 h 的语言。
        • 这就像只使用H for Hello World 已经在HQ9+ 中记录,其中Q 是一个打印程序源代码的命令。此外,9 打印“墙上 99 瓶啤酒”的歌词,+ 增加累加器。巧合的是,我的图形计算器上曾经有一个功能齐全的 HQ9+ 解释器。 :)
        • 你知道,下面的程序实际上是相当多编程语言中的一个 quine:
        • @SamB,真的。 Perl、Python、Ruby 等。但是 OP 有一些针对空程序的东西,所以... :-)
        【解决方案8】:

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

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

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

        【讨论】:

          【解决方案9】:

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

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

          -基兰

          【讨论】:

            【解决方案10】:
            // save it as file.cpp
            
            #include <iostream>
            #include <cstdlib>
            
            using namespace std;
            
            int main()
            {
                system("cat file.cpp"); 
                return 0;
            }
            

            【讨论】:

              【解决方案11】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-12-30
                • 2020-06-05
                • 2012-01-03
                • 1970-01-01
                • 2014-06-22
                • 1970-01-01
                • 1970-01-01
                • 2016-01-02
                相关资源
                最近更新 更多