【Quine】基于Java的实现--输出自身源代码

今天翻看以前的博客,偶然发现以前写过一篇C++的Quine(点我前往),也就是输出自身源代码。闲暇之下,仔细思考了下用Java实现的方法,经过分析和错误尝试,最终得到一个我认为是最简短的Java实现Quine的模式,在此分享我的思考和分析历程。

1.分析Java实现Quine的代码形式

  • 一个Java程序通常是这样的:
package xxx;

public class Xxx{
	public static void main(String[] args) {
		...
	}
}
  • 大致构成就是:packge语句,class申明,main方法,方法体,括号,括号。
  • 这些都是相对静态的语句。如果要输出程序自身的话,这些肯定是最好输出的。
  • 输出这些语句的方式呢?是直接在System.out.println() 里面输出吗?不妨先尝试一下这种方法:
package xxx;

public class Xxx{
	public static void main(String[] args) {
		System.out.println("package xxx;");
	}
}
  • 才写第一条输出语句,是不是发现了什么?如果这样输出的话,那么这条输出语句又怎么输出出来呢?在下面再写一条输出语句输出这一条?一次类推,就无限套娃了,Hhhh。
  • 既然不能直接输出,那么最好的方法就是:把这些语句写到一个字符串数组里,通过这个数组来输出。
  • 这种输出方式就给了输出自身语句一个空间,只要把自身的语句写到字符串数组里,最后统一输出,不久可以了嘛。
  • 于是,能够大概想象到这个程序应该是这个样子的。、
package xxx;

public class Xxx{
	public static void main(String[] args) {
		String s[]= {
		"package Quine;",
        "               ",
        "public class Main {",
        "   public static void main(String[] args) {",
        "       String s[]= {",
		}
		for(int i=0;i<s.length;i++)
            System.out.println(s[i]);
	}
}
  • 当你写到这里的时候,是不是发现了一个问题,这个字符串数组又该怎么输出出来呢?看起来好像又陷入无限循环了。
  • 但是仔细一下,造成我们需要用无限套娃方法来输出这个字符串本身的原因是什么?原因是,我们想通过一条输出语句把这个数组全部输出出来,所以才会遇到这个套娃的困惑。如果我们分开输出,第一次输出先输出前面相对静态的语句(直到创建字符串数组那行),然后再来一个输出语句,把这个字符串数组输出,最后我们还需要一条语句把输出语句的自身输出出来。
  • 综上分析,我们Java实现Quine的代码形式应该是:
package xxx;

public class Xxx{
	public static void main(String[] args) {
		String s[]= {
		"package Quine;",
        "               ",
        "public class Main {",
        "   public static void main(String[] args) {",
        "       String s[]= {",
		}
		//输出字符串数组的前面部分语句
		//输出字符串数组本身的语句
		//输出 输出语句本身
	}
}

2.完善细节,步步突破

  • 通过上面的分析,我们的重点就转到如何写字符串数组和输出语句上了。
  • 第一部分,输出字符串数组的前面部分:只需要将前面部分全部写入字符串数组,然后第一次输出的时候按下标输出,只输出前面部分。具体代码应该是:
package xxx;

public class Xxx{
	public static void main(String[] args) {
		String s[]= {
		"package Quine;",
        "               ",
        "public class Main {",
        "   public static void main(String[] args) {",
        "       String s[]= {",
		}
		for(int i=0;i<=5;i++)
            System.out.println(s[i]);
	}
}
  • 输出结果:可以看到以及达到预期目的了。

在这里插入图片描述

  • 第二部分,输出字符串数组:这里面就有几个小细节了。

    • 第一个细节:里面的双引号要想办法输出出来,这个是字符串数组里面没有的。不可能把这个引号写到字符串数组里转义,不然会影响到其它部分的输出。那么最好的办法就是使用一个char型变量来代替这个引号,在输出的时候将引号一并输出。
    • 第二个细节:字符串数组里面每个字符串在源代码的格式里面前面都是有空格的,要想办法把这几个空格输出出来。把输出空格写到输出语句里面不太好,这样后面输出自身的时候又会涉及到转义,最好的办法还是在字符串数组里面提前把那几个空格写好,直接用字符串数组里面的。可以就写到String s[]= {的下面。
    • 第三个细节:注意每个字符串数组里面,每个字符串结束后的逗号,也要一并输出出来。
  • 具体代码应该是:

package Quine;

public class Main {
    public static void main(String[] args) {
        char c=34;
        String s[]= {
        "package Quine;",
        "               ",
        "public class Main {",
        "   public static void main(String[] args) {",
        "       char c=34;",
        "       String s[]= {",
        "       ",
        "       };",
        "   }",
        "}"
        };
        for(int i=0;i<6;i++)
            System.out.println(s[i]);
        for(int i=0;i<s.length;i++)
            System.out.println(s[6]+c+s[i]+c+',');
    }
}
  • 输出结果:成功输出了字符串数组本身。

在这里插入图片描述

  • 第三部分:输出 输出语句 自身:这个就很简单了,只需要代码写完后,将其复制到字符串数组中就行了,注意输出的格式。

3.最终实现代码(极简)

package Quine;

public class Main {
    public static void main(String[] args) {
        char c=34;
        String s[]= {
        "package Quine;",
        "               ",
        "public class Main {",
        "   public static void main(String[] args) {",
        "       char c=34;",
        "       String s[]= {",
        "       ",
        "       };",
        "       for(int i=0;i<6;i++)",
        "           System.out.println(s[i]);",
        "       for(int i=0;i<s.length;i++)",
        "           System.out.println(s[6]+c+s[i]+c+',');",
        "       for(int i=7;i<s.length;i++)",
        "           System.out.println(s[i]);",
        "   }",
        "}"
        };
        for(int i=0;i<6;i++)
            System.out.println(s[i]);
        for(int i=0;i<s.length;i++)
            System.out.println(s[6]+c+s[i]+c+',');
        for(int i=7;i<s.length;i++)
            System.out.println(s[i]);
    }
}

在这里插入图片描述

思考实现Quine的过程真的比较有趣,建议把所有会的语言的Quine实现方式思考一遍,hhh。

  • 32
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ATFWUS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值