我认为这可能是一个经典问题,但我不知道答案。程序可以输出自身的副本吗?如果可以,是否有一个短程序可以做到这一点?
我不接受“空程序”作为答案,也不接受可以访问自己源代码的程序。相反,我在想这样的事情:
int main(int argc, char** argv){ printf("int main(argc, char** argv){ printf...
但我不知道如何继续......
我认为这可能是一个经典问题,但我不知道答案。程序可以输出自身的副本吗?如果可以,是否有一个短程序可以做到这一点?
我不接受“空程序”作为答案,也不接受可以访问自己源代码的程序。相反,我在想这样的事情:
int main(int argc, char** argv){ printf("int main(argc, char** argv){ printf...
但我不知道如何继续......
是的。可以复制自身的程序称为“quine”。
大多数quines的基本思想是:
您编写的代码采用字符串文字s
并打印它,同时将特殊子字符串foo in的出现(或出现)替换为其自身的值。s
s
到目前为止,您获取了程序的整个源代码并将其用作s
. 但是您从 string中排除了 的定义 ,而是将其替换为foo。s
这是一般的想法。剩下的就是字符串格式的细节,真的。
这称为Quine:
quine 是一种计算机程序,它不接受任何输入并生成其自己的源代码的副本作为其唯一输出。这些程序在可计算性理论和计算机科学文献中的标准术语是自复制程序、自复制程序和自复制程序。
当执行环境被视为一个函数时,quine 是执行环境的固定点。Quines 在任何图灵完备的编程语言中都是可能的,这是 Kleene 递归定理的直接结果。为了消遣,程序员有时会尝试在任何给定的编程语言中开发尽可能短的 quine。
资料来源:维基百科
这确实是一个经典的问题!
除了特定quines的存在之外,可计算性理论的一个重要结果是,对于您可能想要计算的任何函数,都存在一个“知道自己的程序文本”的程序,即如果需要可以打印自己。这个定理被称为Kleene 的第二递归定理。
是的。这是我大约 20 年前编写的一个 C 程序。
如果你写了一个 quine,请注意副本不要无限地写自己的副本并最终接管世界。
在Jon Skeet 发明的语言中,下面的操作符打印“Hello, world!\n”。
h
我可以对这种语言进行修改,以便以下程序打印“Hello, world!\n”:
Hello, world!
这就是打印自己的程序。
哦,你觉得它有些奇怪,而它有一个精确和正确的数学定义?那是你的问题。“我不会接受……”哈!数学确实接受,她是我服务的情妇,所以我发布了这个答案。
我假设您允许解释语言。(在某种程度上,所有语言都被解释。)有人编写解释器,如果你正在编写它,你可以添加任何你喜欢的内置函数,例如一个除了 print " "(foo)
什么都不做的 (lispy) 函数(foo)
.
或者您可以添加更复杂的宏类型函数(printMeAndMyArgs ...)
。
所以诀窍在于你如何定义问题。
Michael Sipser 的“计算理论导论”在其中一章中解释了如何构造一个 quine。我最近基于这个想法编写了一个 Java 程序并将其发布在:http ://bornagainprogrammer.net/2009/11/07/hello-world-from-the-tm-self/
我建议你拿到那本书,尝试用你最喜欢的语言自己实现这个程序。那本书里还有很多其他有趣的定理。
-基兰
// save it as file.cpp
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
system("cat file.cpp");
return 0;
}
在 Java 中是可能的,但有一些限制。
我在 java 中编写了一个简单的代码,它可以自行打印。您可以使用 C/C++ 的文字来使用相同的程序。你可以在这个程序中添加任何你想要的东西,它会完全打印出来。
条件
Java 文件不应在任何包中
文件夹结构不应包含任何名称中带有空格的文件夹
编译目标应该是默认或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);
}
}
}