随机产生20个单词

随机产生20个单词

一、问题来源:

  老师给了一份专业单词word,说第二天要全背下来。错了就五十遍啊五十遍。

  然后,有人提出要做一个产生随机单词的Demo,来测试自己。

  老师表示呵呵,做出来的就可以不用听写。

  顿时,我就表示,是可忍,孰不可忍啊。这是在侮辱我们啊。这票我干了,不能让人看低了。我这么做绝对不是为了逃避五十遍,真的。

二、问题思考:

  写Demo之前,先思考一下这个程序的逻辑。

  首先,我要导入数据,然后将数据转化为便于使用的数据类型。

  导入数据方面,我选择了直接复制,然后以字符串的形式保存在一个数组内。当然,如果在实际使用中更方便。直接将服务器端传输的JSON数据转化就OK了。

  数据转换方面,我原本想着使用正则去识别。然而我发现WebStorm直接将空格和回车都转化出来了。那就方便了。建立一个函数trans来将字符串a转化为我们需要的Object数组。当然你也可以转化为字符串数组。但是我认为转化为Object数组后更易于理解与使用,也更符合逻辑。

  在这之后就是从数组中挑选20个Object出来,显示出来。这涉及到两个问题,首先如何挑选,其次如何显示。

  显示问题,太简单了。直接做一个按钮的监听事件,每一次点击都重新选取。记得每次选取前要初始化,即可。

  

  下面就是这个Demo的最大看点,如何选取20不重复的随机数。当然这个问题,解决方法很多。常用的办法有这两种。(假设源数据数量为count)

  一、建立一个大小为count的数组a,存储的数据从min到max。然后,利用random()方法产生一个随机数randomnumber,从数组a中抽取a[randomnumber],保存在数组b中。之后每次抽取随机数randomnumber,都在数组b中遍历,是否存在。不过不存在就添加。直到数组b的length达到20。

  二、建立一个大小为count的数组a,存储的数据从min到max。然后,利用random()方法产生一个随机数randomnumber,从数组a中抽取a[randomnumber],保存在数组b中,同时将数组a中的a[randomnumber]删除。直到数组b的length达到20。

  上述方法中有一些JS才有的方法,可以加快效率。比如数组的Indexof()方法来查找元素等等。

 

  当然,我的方法和上面有所不同。(否则我也不会这么膨胀)方法如下:

  建立一个大小为count的数组a,存储的数据从min到max。然后,利用random()方法产生一个随机数randomnumber,从数组a中抽取a[randomnumber],保存在数组b中。与此同时,令数组c中c[randomnumber]=1。这样每次产生随机数后,只有在if(!c[randomnumber])条件成立,才向数组b内添加a[randomnumber],同时,数组计数器+1。

  虽然描写看起来更麻烦一些,但是这样就避免了查询已产生随机数的循环遍历的资源消耗。

三、完整代码:

  1 <!DOCTYPE html>
  2 <html lang="zh-cn">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>random-words(20)</title>
  6     <script src="jquery-v1.12.4.js"></script>
  7     <script>
  8     let a = "continue	继续。程序设计中跳出当次循环的关键字。
" +
  9             "break	终止。程序设计中终止循环的关键字。
" +
 10             "next	下一个。
" +
 11             "function	函数。程序设计中定义函数的关键字。
" +
 12             "return	返回。程序设计中函数返回数据的关键字。
" +
 13             "true	真的
" +
 14             "false	假的
" +
 15             "var	定义变量关键字。
" +
 16             "int	整型。
" +
 17             "boolean	布尔型。
" +
 18             "float	浮点型数值。
" +
 19             "double	双精度数值。
" +
 20             "class	类。定义类的关键字。
" +
 21             "public	公有的。
" +
 22             "private	私有的。
" +
 23             "static	静态的。
" +
 24             "super	超级。代指面向对象编程中父级类。
" +
 25             "this	这个。一般指当前对象。
" +
 26             "window	窗口。DOM中的浏览器窗口对象。
" +
 27             "document	文档。DOM中的文档对象。
" +
 28             "width	宽度
" +
 29             "height	高度
" +
 30             "first	第一个。
" +
 31             "last	最后的。
" +
 32             "parent	父亲,父级。
" +
 33             "append	追加。
" +
 34             "before	之前
" +
 35             "after	之后
" +
 36             "focus	焦点。CSS中的伪类名称,常用于设计控件获得焦点时的效果
" +
 37             "hover	悬停。CSS中的伪类名称,常用于设计鼠标经过效果
" +
 38             "select	选择。HTML中的下拉框标签名
" +
 39             "checkbox	复选框
" +
 40             "submit	提交
" +
 41             "reset	重置
" +
 42             "click	单击事件
" +
 43             "keyup	键盘松开事件
" +
 44             "keydown	键盘按下事件
" +
 45             "mouseup	鼠标松开或者弹起事件
" +
 46             "mousedown	鼠标按下事件
" +
 47             "empty	空的
" +
 48             "remove	移除
" +
 49             "array	数组
" +
 50             "show	显示
" +
 51             "hide	隐藏
" +
 52             "animate	动画。jQuery中的自定义动画方法。
" +
 53             "event	事件
" +
 54             "replace	替换
" +
 55             "join	数组方法之一,将元素合并成字符串
" +
 56             "split	字符串方法之一,将字符串切割成数组
" +
 57             "splice	数组方法之一,可增、删、改元素
" +
 58             "underline	下划线
" +
 59             "fixed	定位元素的样式属性值之一,固定定位
" +
 60             "position	定位元素的样式属性名
" +
 61             "align	对齐方式
" +
 62             "background	设置元素背景的属性名
" +
 63             "display	显示
" +
 64             "solid	边框线条样式值之一,实线类型
" +
 65             "clear	清除,清理
" +
 66             "element	元素
" +
 67             "home	家,或首页
" +
 68             "middle	中间的,垂直居中样式值
" +
 69             "center	水平居中
" +
 70             "button	按钮
" +
 71             "hidden	被隐藏的
" +
 72             "important	重要的,提升样式的优先级
" +
 73             "margin	元素外边距属性名
" +
 74             "object	对象
" +
 75             "transform	变换,设置CSS3变换的样式属性名称
" +
 76             "relative	相对的,定位属性值之一的相对定位
" +
 77             "arguments	参数集合,LESS混合中或者JS函数中代表参数集合
" +
 78             "method	方法
" +
 79             "action	动作,表单form的属性之一
" +
 80             "number	数字或数值,JavaScript中的数据类型之一
" +
 81             "translate	平移,用于设置元素的位置
" +
 82             "padding	元素内间距属性名
" +
 83             "source	来源
" +
 84             "control	控制或控件
" +
 85             "video	视频,H5新增播放视频的标签名
" +
 86             "default	默认的,缺省的
" +
 87             "container	容器
" +
 88             "content	内容
" +
 89             "textarea	文本输入域的标签名称
" +
 90             "current	当前的
" +
 91             "visited	已经访问过的
" +
 92             "inner	内部的
" +
 93             "outer	外部的
" +
 94             "client	客户端
" +
 95             "location	位置,定位
" +
 96             "instance	实例
" +
 97             "prototype	原型对象
" +
 98             "property	属性
" +
 99             "constructor	构造函数
" +
100             "innerWidth	内部宽度
" +
101             "prepend	在元素内部前置插入元素
" +
102             "trigger	主动触发事件
" +
103             "triggerHandler	主动触发事件,但不触发浏览器默认事件
" +
104             "fadeIn	淡入动画方法
" +
105             "fadeOut	淡出动画方法
" +
106             "currentTarget	总是指向事件监听目标对象
" +
107             "focusin	元素获得焦点时触发事件的方法
";
108     </script>
109     <style>
110         .container{
111             border     : 5px solid #333333;
112             padding    : 30px;
113             background : sandybrown;
114         }
115         .top-container{
116             width: 100%;
117             height: 50px;
118         }
119         .headtitle{
120             display: block;
121             float: left;
122             position: relative;
123             width: 300px;
124             font-size: 24px;
125             text-align : center;
126         }
127         .ebuttom{
128             display: block;
129             float: left;
130             top:5px;
131             left: 20%;
132             position: relative;
133             width: 200px;
134             font-size: 20px;
135             text-align : center;
136             background: lightgrey;
137             border-radius: 5px;
138             box-shadow: 0px 1px 1px;
139 
140         }
141         .but-container{
142             width: 100%;
143             height: 50px;
144             position: relative;
145             top:20px;
146         }
147         .content{
148             width: 100%;
149             height:480px;
150             position: relative;
151             top:20px;
152             font-size: 18px;
153         }
154         .word{
155             display: block;
156             float: left;
157             position: relative;
158             width:20%;
159             text-align : center;
160         }
161         .explain{
162             display: block;
163             float: left;
164             position: relative;
165             width: 80%;
166             text-align : center;
167         }
168         .title{
169             font-size: 20px;
170         }
171         .content>.explain{
172             left:10%;
173             text-align: left;
174         }
175     </style>
176 </head>
177 <body>
178     <div class="container">
179 
180         <div class="top-container">
181             <div class="headtitle">专业单词测试</div>
182             <div class="ebuttom" onclick="changewordlist()">产生随机单词</div>
183         </div>
184         <!--<h2 class="word">单词</h2>-->
185         <!--<div class="explain">解释</div>-->
186         <div class="but-container">
187             <div class="title word">单词</div>
188             <div class="title explain">解释</div>
189         </div>
190 
191     </div>
192 
193     <script>
194     let wordsBase = new Array();
195     let count=20;
196     let wordlistf=new Array();
197     /**
198      * 用于将基础的字符串转换为需要的Object数组
199      * @ps 由于我们是通过
来分解字符串,而字符串最后有一个/n,所以length得减一。
200      * a [string]
201      * return Array
202      */
203     function trans( a )
204     {
205 
206         let wordesArray = a.split( "
" );
207 
208         for( let i = 0; i < wordesArray.length - 1; i++ )
209         {
210             let wordArray = wordesArray[ i ].split( "	" );
211             let word = wordArray[ 0 ];
212             let explain = wordArray[ 1 ];
213             let wordBase = {
214                 word: word,
215                 explain: explain
216             };
217             wordsBase.push( wordBase );
218         }
219         return wordsBase;
220     }
221     wordsBase=trans(a);
222 
223     /**
224      *  用于从min到max中输出count个不重复随机数字。
225      * @param count number
226      * @param min   number
227      * @param max number
228      */
229     function norepeatRandom( count, min, max )
230     {
231         let resultArray = [];
232         //        resultArray.length = 20;
233         let markArray = [];
234         //        markArray.length = 100;
235         //        console.log(1,resultArray.length,markArray.length);
236         //确保可以取到max
237         let range = max - min + 1;
238         for( let i = 0; i < count; )
239         {
240             let randomnumber = (range * Math.random() + min) >> 0;
241             if( !markArray[ randomnumber ] )
242             {
243                 resultArray[ i ] = randomnumber;
244                 markArray[ randomnumber ] = 1;
245                 i++;
246             }
247         }
248         return resultArray;
249     }
250 
251     /**
252      *  用于从Object数组wordlist中获取数组randomlist中数字指向的Object元素,并且组成新的数组,返回。
253      * @param wordlist Array
254      * @param randomlist   Array
255      */
256     function randomArray( wordlist,randomlist )
257     {
258         let wordlist20=[];
259         for(let i=0;i<randomlist.length;i++){
260             wordlist20[i]=wordlist[randomlist[i]];
261             wordlist20[i]=wordlist[randomlist[i]];
262         }
263         return wordlist20;
264     }
265 
266 
267     /**
268      * 点击产生新的随机单词list
269      * @param e 获取单击事件
270      */
271     function changewordlist( e )
272     {
273         e = event || window.event;
274         wordlistf=randomArray( wordsBase,norepeatRandom( 20, 0, 99 ) );
275         let count=20;
276         let $contentinit=$(".container>.content");
277         if($contentinit.length){
278             console.log($contentinit);
279             $contentinit.remove();
280         }
281 
282 
283         $(".container>.but-container").after( "<div class="content"></div>
");
284         for(let i=0;i<count;i++){
285             let wordf=wordlistf[i].word;
286             let explainf=wordlistf[i].explain;
287             let $content=$(".container>.content");
288             $content.append( "<div class="word">"+wordf+"</div>
" +
289                              "			<div class="explain">"+explainf+"</div>");
290 //            $content.append( "<div class="word">单词</div>
" +
291 //                             "			<div class="explain">解释</div>");
292         }
293     }
294     </script>
295 </body>
296 </html>

 四、题后思考:

  那么问题来了。在之前问题思考中,有一个JS的index()方法,来实现这个算法。那么到底哪个算法会节省系统资源呢?

  之后我想写一个相关的测试函数,运算时间方面,完全可以在测试函数的开头与结尾都获取一个时间戳,通过两者的差值就可以算出这个算法的运行时间。那么内存、运算量等相信也可以通过一些方法解决。但是如何提高这个测试函数的通用性,也就是如何让这个测试函数可以测试多个类型的算法呢,毕竟不同的算法有着不同的参数,有时候还需要调用个函数等等。所以这个思考分为两个部分,一个是这个算法的性能测试,一个是测试函数的拓展。

 

原文地址:https://www.cnblogs.com/Tiancheng-Duan/p/7724794.html