这几天在论坛上看到了一个很有意思的项目,一个生成“狗屁不通”的文章的程序。经过本人确定其的确是“狗屁不通”后,随后又好奇其实现,于是在其[GitHub]项目里(https://github.com/menzi11/BullshitGenerator)找到源码,研究了半晌。

我看的是网页版的,就是JS文件里的核心代码。

作者使用了大量的中文变量名,请谨慎阅读,若有不适请立即离开

声明的String数组--组成文章的核心内容

let 主题 = "一天掉多少根头发";    //用户输入的文字(会围绕该文字“生成”文章)

let 论述 = [
"现在,解决主题的问题,是非常非常重要的。 所以, ",
"我们不得不面对一个非常尴尬的事",
//略,这里有很多的这种论述 ]; let 名人名言 = [
"伏尔泰曾经说过,不经巨大的困难,不会有伟大的事业。这不禁令我深思",
"富勒曾经说过,苦难磨炼一些人,也毁灭另一些人。这不禁令我深思",
//略,这里有很多名人名言]; let 后面垫话 = [
"这不禁令我深思。 ",
"带着这句话,我们还要更加慎重的审视这个问题: ",
"这启发了我, ",]; let 前面垫话 = [
"曾经说过",
"在不经意间这样说过",
];

上面的字符串数组是此程序的“基石”,也是可以通过修改其内容从而改变文章“内容”的重要备份

声明的几个函数--“合成”文章的核心算法

function 随便取一句(列表){   //30*0.8  = 24
let 坐标 = Math.floor( Math.random() * 列表.length ); //向下取整(小于等于她的最接近他的整数)
return 列表[坐标]; //数组中某一句
};

上面的函数用于从个数组中取句子。

传入的参数就是上面定义的数组的名字,同时返回一句。

function 随便取一个数(最小值 = 0,最大值 = 100){
let 数字 = Math.random()*( 最大值 - 最小值 ) + 最小值; //math返回一个0.0-1.0之间的随机数
return 数字;
}

上面的函数用于生成1-100的随机数。后面会讲到他的作用

function 来点名人名言(){
let 名言 = 随便取一句(名人名言) //名人名言是数组名
名言 = 名言.replace("曾经说过", 随便取一句(前面垫话) ) //前面垫话和后面垫话均是数组名
名言 = 名言.replace("这不禁令我深思", 随便取一句(后面垫话) )
return 名言;
}

该函数的作用就和他的名字一样,取一条名人名言。(会用到“随便取一句”这个函数。

我们可以看到,在他的函数里面,当他取到名人名言的时候,对这个句子的前面垫话和后面垫话进行了替换。保证了名人名言某种程度地多样性。(名人名言中的每句名人名言都有“曾经说过”和“这不禁令我深思”);

function 来点论述(){
let 句子 = 随便取一句(论述);
句子 = 句子.replace(RegExp("主题", "g"),主题); //g表示全局匹配 //使用正则进行替换,有点不懂
return 句子;
}

上面的函数用于 提取“论述”。

在提取到“论述”后,该函数使用正则对每个论述中的“主题”两字用读者输入的主题变量进行了替换。

也就是说,我们输入的关键词全部都会集中在这个函数生成的论述中。

function 增加段落(章节){
if(章节[章节.length-1] === " "){
章节 = 章节.slice(0,-2) //去掉章节后面的多余的字符 ,便于后面再后面增加句号。
}
return "  " + 章节 + "。 "
}

该函数用于“增加段落”。

对“章节”进行缩进和去掉末尾的空格,并加上句号。

核心函数

function 生成文章(){
let 文章 = []
for(let 空 in 主题){ //遍历字符串的每个元素(可能没有用到空,他只是用于控制循环的次数
let 章节 = "";
let 章节长度 = 0; //章节长度值得是字符的个数
while( 章节长度 < 6000 ){
//这个循环并不是只添加一个段落,当循环结束后会添加很多个段落。
//当添加的文字总数达到6000时会跳出循环,
let 随机数 = 随便取一个数();
if(随机数 < 5 && 章节.length > 200){
章节 = 增加段落(章节); //增加章节(章节长度>200时就添加章节了)。
文章.push(章节);
章节 = ""; //<5的随机数进行的操作 //有很小的几率添加到文章中
}else if(随机数 < 20){
let 句子 = 来点名人名言();
章节长度 = 章节长度 + 句子.length;
章节 = 章节 + 句子; //>5 且<20的随机数进行的操作 //添加名人名言:有五分之一的几率
}else{
let 句子 = 来点论述();
章节长度 = 章节长度 + 句子.length;
章节 = 章节 + 句子; //大于等于20的随机数进行的操作
}
}
章节 = 增加段落(章节);
文章.push(章节);
}
return 文章.join("\n");
}

我们会很快注意到这个有点复杂的函数中的那一个while循环,我们先来看她。

while( 章节长度 < 6000 )

这里的判断条件刚开始迷惑了我很久,让我一直以为这是在控制段落的字符数,其实不是的,她是控制本次生成段落的总字数(也就是说这个循环执行一次会生成很多的段落,并且他们的总字符数是6000(不一定一定是6000))。

我们在看while外面的那个for循环:

for(let 空 in 主题)

“主题”是一个字符串,这个循环就是遍历主题中的每一个字符,遍历的次数就是这个for循环执行的次数,也就是他内部的(我们上面提到的)while循环执行的次数。

那么我么现在就可以知道了一件很重要的事情了:生成文章的总字数 = 输入的字符数*6000 (大约)。

*************************************************************

while中有三个if else

他们通过生成的随机数控制文章中名人名言和论述所占的部分(这是个令我很惊讶的算法)。

最后,是程序的启动开关

console.log(生成文章())

​ 2019年11月6日晚 20:52

【狗屁不通文章生成器】代码分析 (javaScript)的更多相关文章

  1. “狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作

    一.垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高. 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介 ...

  2. JQuery html API支持解析执行Javascript脚本功能实现-代码分析

    JQuery html用法(功能类似innerHTML) 开发中需要使用Ajax技术来更新页面局部区域, 使用的方法是ajax获取html代码段(字符串),然后将这个html代码段作为参数,传入目标D ...

  3. 几篇QEMU/KVM代码分析文章

    QEMU/KVM结合起来分析的几篇文章,代码跟最新的版本有些差异,但大体逻辑一样,写得通俗易懂.我把链接放这里主要是为自己需要查看时调转过去方便,感谢作者的付出! QEMU Source Code S ...

  4. 分析JavaScript代码应该放在HTML代码哪个位置比较好

    本文总结了多种放置JS代码的方法,需要的朋友可以参考下 在哪里放置 JavaScript 代码? 通常情况下,JavaScript 代码是和 HTML 代码一起使用的,可以将 JavaScript 代 ...

  5. 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)

    构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...

  6. iOS 使用UIWebView把oc代码和javascript相关联

    首先请参看一篇文章,作者写的很明白,请参看原地址 http://blog.163.com/m_note/blog/static/208197045201293015844274/. 其实,oc和js的 ...

  7. AngularJS PhoneCat代码分析

    转载自:http://www.tuicool.com/articles/ym6Jfen AngularJS 官方网站提供了一个用于学习的示例项目:PhoneCat.这是一个Web应用,用户可以浏览一些 ...

  8. XSS原理及代码分析

    前言 XSS又叫跨站脚本攻击,是一种对网站应用程序的安全漏洞攻击技术.它允许恶意用户将代码注入网页,其他用户在浏览网页时就会受到影响.XSS分为三种:反射型,存储型,和DOM型.下面我会构造有缺陷的代 ...

  9. [Asp.net 5] DependencyInjection项目代码分析-目录

    微软DI文章系列如下所示: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Autofac [ ...

随机推荐

  1. pt-online-schema-change在线修改脚本

    pt-online-schema-change在线修改脚本 经过几次在测试环境中使用,发现5.6和5.7可以正常使用.mysql8.0.18版本中,竟然无法使用,感到惊讶.难道mysql8.0.18强 ...

  2. ICPC — International Collegiate Programming Contest Asia Regional Contest, Yokohama, 2018–12–09 题解

    目录 注意!!此题解存在大量假算法,请各位巨佬明辨! Problem A Digits Are Not Just Characters 题面 题意 思路 代码 Problem B Arithmetic ...

  3. BZOJ 1901 洛谷 P2617 ZOJ 2112 Dynamic Rankings

    以下时空限制来自zoj Time limit 10000 ms Memory limit 32768 kB OS Linux Source Online Contest of Christopher' ...

  4. 【bzoj3223】Tyvj 1729 文艺平衡树

    题目描述: 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 输入 ...

  5. Python语言中enumerate()及zip()函数的使用例子

    在Python编程语言中,enumerate()及zip()是两个常用的内置函数,这两个函数功能类似,但又有所区别,下面通过两个例子分别进行说明. enumerate()函数 该函数在字面上是枚举.列 ...

  6. Java数据结构之排序---希尔排序

    希尔排序的基本介绍: 希尔排序同之前的插入排序一样,它也是一种插入排序,只不过它是简单插入排序之后的一个优化的排序算法,希尔排序也被称为缩小增量排序. 希尔排序的基本思想: 希尔排序是把数组中给定的元 ...

  7. linux grep 正则

    grep : 显示匹配行 -v: 反显示 -e 使用扩展正则表达式 黑色字体表明是原生正则表达式 红色字体表明是扩张正则表达式 1.匹配操作符 \: 转义字符串(正则使用扩展字符操作  没有使用-e ...

  8. 将数据库中带出的列,在gridview中影藏起来

    前台增加事件:OnRowCreated="GridView1_RowCreated" protected void GridView1_RowCreated(object send ...

  9. Mac securecrt 破解版安装

    破解一 1.先链接:https://pan.baidu.com/s/1-1nu4eRf7BmuLg5MtlCRvw  密码:30pq    默认下载到了当前用户的”下载”目录中 在”Finder”中 ...

  10. 3、electron打包生成exe文件

    打包方式1:DOS窗口命令打包 DOS 下,输入 npm install electron-packager -g全局安装我们的打包神器: cnpm install electron-packager ...