文章目录
- 设计一个数组输入并显示的程序。
- 数组输入和显示
- 选择排序
- 选择排序
- 排序程序包
- 排序网页
- 杨辉三角形
- 杨辉三角形网页
- C语言画一个sin(x)的曲线
- 螺旋线访问二维数组
JavaScript数组
的定义、使用都是非常简单的,仅仅定义的话,就使用:
var a=new Array();
对于JavaScript的数组,大小不用管的,爱用多大的下标就用多大。
设计一个数组输入并显示的程序。
对后续的实验而言,要求能有一个数组、能输入数据、并显示结果,为满足这个要求,程序至少要有三个按钮:数据输入、数据显示、数组清除,所谓数组清除,就是当你的数据输入错误后,要能清除掉这个数组、给使用者重新输入的机会。后面肯定就是个文本框了。所以这种情况下,控件说明就是这样的:
<INPUT TYPE="button" ID=BUTTON1 value="数据输入" onclick='fIn()' />
<INPUT TYPE="button" ID=BUTTON2 value="数据输出" onclick='fOut()' />
<INPUT TYPE="button" ID=BUTTON2 value="数据清除" onclick='fCls()' />
<INPUT TYPE="input" ID="text1" style="z-index: 100; left: 11px; width: 248px; position: absolute; top: 40px"/>
注意这个text1控件的说明:它同过去的定义不一样,而是说明了位置属性,left:11px,说明这个控件离浏览器左边10个像素点,width:248px说明该控件宽度是248像素点,而后面的top:40px、则说明离浏览器高度是40个像素点。
我们可以打开a2.htm,这个网页文件,把上述控件说明写进去,并另存为a19.htm
分析:对于数组,我们定义一个就足够了,注意我们的数组、要在三个函数:fIn()、fOut()、fCls()中使用,所以,这个数组应该是全局的,同理,数组的大小也需要知道,我们用n来存储它的当前大小,n也应该是全局的、并且开始就是0,所以程序框架结构就是:
var a=new Array();
var n=0;
function fIn()
{…
}
function fOut()
{…
}
fCls()
{…
}
对于fIn()函数,就是从text1中读到数据并给到a[ ],所以是:
function fIn()
{var d=parseInt(text1.value);a[n]=d;n++;text1.value=””;
}
n++的含义是准备写到下一个数组单元里。
而对fOut(),也很简单,就是:
function fOut()
{var i;for(i=0;i<n;i++)document.write(a[i]+"<br>");
}
对多个数据的显示,我们选择document.write(),这样可以显示很多数据。
而对于fCls(),则使用重新构造数组并将n=0,这样,旧的数据就全没了
function fCls()
{a=new Array();n=0;
}
把上述代码全部凑到一起,构成新的网页,实际通过上述很多范例的分析,我们知道基本过程就是:
(1) 打开一个框架程序、如a2.htm这样的文件;
(2) 在框架文件里先填加控件的说明,让你的程序有足够的控件;
(3) 注意控件的事件响应函数的名称,不要搞错;
(4) 补充你的事件响应函数,到此就算完成了。
(5) 整个程序就是:
文件名:a19.htm
数组数据的输入和显示
<HTML><HEAD><TITLE>数组的输入</TITLE><SCRIPT TYPE="TEXT/JAVASCRIPT">//这里要加入的是JAVASCRIPT的代码var n=0;var a=new Array();function fIn(){var d=parseInt(text1.value);a[n]=d;n++;}function fOut(){var i;for(i=0;i<n;i++)document.write(a[i]+"<br>");}function fCls(){a=new Array();n=0;}</SCRIPT></HEAD><BODY BGCOLOR="#FF1234"><DIV><INPUT TYPE="button" ID=BUTTON1 value="数据输入" onclick='fIn()' /><INPUT TYPE="button" ID=BUTTON2 value="数据输出" onclick='fOut()' /><INPUT TYPE="button" ID=BUTTON3 value="数据清除" onclick='fCls()' /><INPUT TYPE="input" ID="text1" style="z-index: 100; left: 11px; width: 248px; position: absolute; top: 40px"/></DIV></BODY>
</HTML>
数组输入和显示
这个程序的关键地方是要把事件响应函数和每个控件对应起来。
有了上述程序,后面的作业就可以逐个去完成了。所谓框架、这个程序就算一个吧,在这个程序基础上继续补充,就会非常方便。
选择排序
排序是一个很有意思的事情,选择排序的程序就是:
function SelectSort(x,num)
{var i,j,t,m,min;for(i=0;i<num;i++){min=a[i];m=i;for(j=i;j<num;j++)if(x[j]<min){min=x[j];m=j;}if(m!=i){t=x[i];x[i]=x[m];x[m]=t;}}
}
其中x是一个数组,保存着待排数据,num是这个数组的大小。
查阅JavaScript,可以发现JavaScript得到数组长度很方便,就是x.length、或者是a.length,这样,我们再次修改SelectSort()就是:
function SelectSort(x)
{var i,j,t,m,min;var num=x.length;for(i=0;i<num;i++){min=a[i];m=i;for(j=i;j<num;j++)if(x[j]<min){min=x[j];m=j;}if(m!=i){t=x[i];x[i]=x[m];x[m]=t;}}
}
注意这个函数:它没针对a数组排序,实际就是说可以针对任何一个数组排序,所以需要一个主调函数去调用它,这个主调函数应该是一个按纽的事件响应函数。于是要再增加一个按纽:选择排序,就是:
注意它的事件响应函数是fSort(),于是补充函数:
function fSort()
{SelectSort(a);
}
这样,整个程序就是:
文件:a20.htm
选择排序
<HTML><HEAD><TITLE>选择排序</TITLE><SCRIPT TYPE="TEXT/JAVASCRIPT">//这里要加入的是JAVASCRIPT的代码var n=0;var a=new Array();function SelectSort(x){var i,j,t,m,min;var num=x.length;for(i=0;i<num;i++){min=a[i];m=i;for(j=i;j<num;j++)if(x[j]<min){min=x[j];m=j;}if(m!=i){t=x[i];x[i]=x[m];x[m]=t;}}}function fIn(){var d=parseInt(text1.value);a[n]=d;n++;text1.value="";}function fOut(){var i;for(i=0;i<n;i++)document.write(a[i]+"<br>");}function fCls(){a=new Array();n=0;}function fSort(){SelectSort(a);}</SCRIPT></HEAD><BODY BGCOLOR="#FF1234"><DIV><INPUT TYPE="button" ID=BUTTON1 value="数据输入" onclick='fIn()' /><INPUT TYPE="button" ID=BUTTON2 value="数据输出" onclick='fOut()' /><INPUT TYPE="button" ID=BUTTON3 value="数据清除" onclick='fCls()' /><INPUT TYPE="button" ID=BUTTON4 value="选择排序" onclick='fSort()' /><INPUT TYPE="input" ID="text1" style="z-index: 100; left: 11px; width: 248px; position: absolute; top: 40px"/></DIV></BODY>
</HTML>
选择排序
从上述程序我们可以看到:我们的程序已经开始逐渐变大,实际上选择排序并不是很大,但现在,我们要假设:我们的排序程序非常大,实际中,排序要好多种方法。
把一个很大的程序包装在一个网页里、并不明智,这会让这个网页打开过程非常慢,于是我们要想办法把网页内容分割成一些小包,比如我们的排序程序,要从a20.htm中分割出来。分割过程如下:
1 我们先打开记事本,把SelectSort()函数复制过去、另存为Sort.js;
2 把SelectSort()从a20.htm中删除掉、a20.htm另存为a21.htm;
现在我们肯定知道:a21.htm必须引用Sort.js才能进行排序,否则fSort()函数里根本找不到SelectSort()在哪里。引用一个程序包、如Sort.js,使用的语句是:
<SCRIPT TYPE="TEXT/JAVASCRIPT" src="sort.js"></SCRIPT>
注意src=””这个描述,它代表的是从本地硬盘、当前文件夹中引用这个程序包,也可以是这样的描述:
这代表着将从一个网站:www.abcd.com上获得这个程序包。
在实际中,由于浏览器都采用了多线程技术、网站也有很多端口,分割成小包文件下载、速度要快的多。
这样,整个程序就是:
文件名:Sort.js
排序函数包,目前仅仅是选择排序
function SelectSort(x)
{var i,j,t,m,min;var num=x.length;for(i=0;i<num;i++){min=a[i];m=i;for(j=i;j<num;j++)if(x[j]<min){min=x[j];m=j;}if(m!=i){t=x[i];x[i]=x[m];x[m]=t;}}
}
排序程序包
文件:a21.htm
调用排序包的排序网页
<HTML><HEAD><TITLE>选择排序</TITLE><SCRIPT TYPE="TEXT/JAVASCRIPT" src="sort.js"></SCRIPT><SCRIPT TYPE="TEXT/JAVASCRIPT">//这里要加入的是JAVASCRIPT的代码var n=0;var a=new Array();function fIn(){var d=parseInt(text1.value);a[n]=d;n++;text1.value="";}function fOut(){var i;for(i=0;i<n;i++)document.write(a[i]+"<br>");}function fCls(){a=new Array();n=0;}function fSort(){SelectSort(a);}</SCRIPT></HEAD><BODY BGCOLOR="#FF1234"><DIV><INPUT TYPE="button" ID=BUTTON1 value="数据输入" onclick='fIn()' /><INPUT TYPE="button" ID=BUTTON2 value="数据输出" onclick='fOut()' /><INPUT TYPE="button" ID=BUTTON3 value="数据清除" onclick='fCls()' /><INPUT TYPE="button" ID=BUTTON4 value="选择排序" onclick='fSort()' /><INPUT TYPE="input" ID="text1" style="z-index: 100; left: 11px; width: 248px; position: absolute; top: 40px"/></DIV></BODY>
</HTML>
排序网页
有了这样的程序包,我们编写其他排序函数也就方便的多。现在我们首先在Sort.js中补充一个冒泡排序函数,所以首先打开Sort.js文件,补充代码如下:
function BubbleSort(x)
{var num=x.length;var i,j,t;for(i=0;i<=num-2;i++)for(j=0;j<=num-i-1;j++)if(x[j]>x[j+1]) {t=x[j];x[j]=x[j+1];x[j+1]=t;}
}
有了这个排序函数后,在a21.htm中修改:
function fSort()
{BubbleSort(a);
}
这样就能调用BubbleSort()函数进行排序了。如果你不希望每次都输入数据,你还可以修改成这样:
function fSort()
{a=[2,4,6,8,10,1,3,5,7,9];n=10;BubbleSort(a);
}
最后,在Sort.js中补充一个新的排序方法RadixSort(),自己分析一下算法。
杨辉三角形
这个三角形就是:
实际,就是(a+b) 、当n=1,2,3,4….时候的系数。分析这个三角形还是不难发现其规律的。于是设计中可以用一个二维数组,先把每行最开始的数字和最末尾的数字写进去:
#include<stdio.h>
main()
{
int i,j,a[10][10];
for(i=0;i<10;i++)for(j=0;j<10;j++)a[i][j]=0;//每行最开始的和最末尾的数字都是1for(i=0;i<10;i++){a[i][0]=1;a[i][i]=1;}for(i=0;i<10;i++){for(j=0;j<10;j++)printf("%d ",a[i][j]);printf("\n");}
}
真正的处理是这样的:
for(i=2;i<10;i++)for(j=1;j<i;j++)a[i][j]=a[i-1][j-1]+a[i-1][j];
就是前一行的前一个+前一行的当前列的值。
于是整个程序就是:
#include<stdio.h>
main()
{
int i,j,a[10][10];
for(i=0;i<10;i++)for(j=0;j<10;j++)a[i][j]=0;//先把每行的开始结束值给成1for(i=0;i<10;i++){a[i][0]=1;a[i][i]=1;}//前一行前一列+前一行当前列for(i=2;i<10;i++)for(j=1;j<i;j++)a[i][j]=a[i-1][j-1]+a[i-1][j];//显示每行每列for(i=0;i<10;i++){for(j=0;j<10;j++)if(a[i][j]!=0)printf("%d ",a[i][j]);printf("\n");}
}
另外一种算法是根据这个三角形的基本性质,导出了通项公式,所以更加简洁。C语言的程序见下面的范例。
#include<stdio.h>
main()
{
long i,j,n,k;
scanf("%ld",&n);
for(i=1;i<=n;i++) { k=1; for(j=1;j<i;j++) { printf("%ld ",k); k=k*(i-j)/j; } printf("1\n"); }
}
但我们不仅仅做C语言的程序,我们要做的是浏览器下的程序。我们还是考虑使用2维数组的情况,其主要目的是让大家学会JavaScript怎么处理2维数组。
对上述的C语言程序,它仅仅能处理10行,而对JavaScript、则这个是可以由用户自由输入并打印的。所以我们的浏览器上要一个文本框、一个按钮就足够了。所以控件的说明就是:
<INPUT TYPE="button" ID=BUTTON1 value="杨辉三角" onclick='fun()'/>
<INPUT TYPE="input" ID="text1" />
注意按钮的事件响应函数是fun()
但我们查阅JavaScript语言,却发现这个语言没有直接说可以有二维数组,它仅仅是有一维数组的定义,但这不要紧,我们可以自己构造。首先可以想象一维数组就是二维数组的一列,在二维数组上、这一列本身又是个一维数组,于是就有:
function fun(){var n=parseInt(text1.value);//先申请a是一维数组var a=new Array(n);//这里是一维数组var i,j;for(i=0;i<n;i++){
//注意,一维数组的每个元素还是数组,为每个a[i]再次申请个//数组,这//样就构造了二维数组a[i]=new Array();for(j=0;j<n;j++)a[i][j]=0;}}
这样分两次构造,就可以把a变成2维数组,实际还可以是3维、4维等等。对这个数组赋值,同C语言是一样的,比如对每行第1个和杨辉三角每行最后一个赋值,就是这样的程序:
for(i=0;i<n;i++){a[i][0]=1; a[i][i]=1;}
对第2行后的数据进行计算,就是:
for(i=2;i<n;i++)for(j=1;j<i;j++)a[i][j]=a[i-1][j-1]+a[i-1][j];
同C语言完全一致的语句,所以整个程序就是:
文件名称:a22.htm
杨辉三角形
<HTML><HEAD><TITLE>杨辉三角形</TITLE><SCRIPT TYPE="TEXT/JAVASCRIPT">//这里要加入的是JAVASCRIPT的代码function fun(){var n=parseInt(text1.value);//先申请a是一维数组var a=new Array(n);var i,j;for(i=0;i<n;i++){//注意,一维数组的每个元素还是数组,这样就构造了二维数组a[i]=new Array();for(j=0;j<n;j++)a[i][j]=0;}for(i=0;i<n;i++){a[i][0]=1;a[i][i]=1;}for(i=2;i<n;i++)for(j=1;j<i;j++)a[i][j]=a[i-1][j-1]+a[i-1][j];for(i=0;i<n;i++){for(j=0;j<n;j++)if(a[i][j]!=0)document.write(a[i][j]+" ");document.write("<br>");}}</SCRIPT></HEAD><BODY BGCOLOR="#00FF00"><DIV><INPUT TYPE="button" ID=BUTTON1 value="杨辉三角" onclick='fun()'/><INPUT TYPE="input" ID="text1" /></DIV></BODY>
</HTML>
杨辉三角形网页
上述程序可以计算的层很多,基本上看你机器能力了,这点是C语言不能比拟的,JavaScript的灵活性太好了。
这个题目实际来自海盗分财游戏,说的是17人循环排队,数到3则该人拉出去砍了,再次报数从1到3,……直到最后一人留下。
这首先要有个17个数的a数组,假设开始是1~17,一轮报数砍掉的归0,比如a[2]=3,拉出来砍掉就是a[2]=0;
有了这样的假设,统计活着的人就很必要,所以有函数:
#include<stdio.h>
#define N 17
int Live(int a[ ])
{int i,m=0;for(i=0;i<N;i++)if(a[i]>0) m++;return m;
}
每次砍掉一批人,直到活下1人,主程序框架就是:
while(Live(a)>1)
{
//每人报数、砍人
}
所以主程序就非常简单:
main()
{
int i,j,a[N],n=0;
for(i=0;i<N;i++) a[i]=i+1;
while(Live(a)>1){for(i=0;i<N;i++){if(a[i]!=0) n++; //活着的计数,死的不算if(n==3) {a[i]=0;n=0;}//数到3砍人、点名的归0}//每轮点名后显示结果,分析吧。for(i=0;i<N;i++)printf("%4d",a[i]);printf("\n");}
}
把上述程序转到JavaScript是很容易的事情,对JavaScript、你甚至可以随便指定人或者随便指定点名人数,所以有以下的界面:
<INPUT TYPE="button" ID=BUTTON1 value="点名开杀" onclick='fun()'/>
<INPUT TYPE="input" ID="text1" />
<INPUT TYPE="input" ID="text2" />
我们在text1中输入排队的人数、在text2中输入砍人的计数人数、如上例的3人。注意按钮的事件响应函数是fun()。
上述程序的修改很容易,注意点在:
1 修改main( )为fun( )
2 修改printf()为document.write( )
3 修改”\n”为”
”
整个程序就是:
文件:a23.htm
作业5.7
<TITLE>海盗分财</TITLE><SCRIPT TYPE="TEXT/JAVASCRIPT">//这里要加入的是JAVASCRIPT的代码function Live(a){var i,m=0;for(i=0;i<a.length;i++)if(a[i]>0) m++;return m;}function fun(){var n=0,i=0,N,M;N=parseInt(text1.value);M=parseInt(text2.value);var a=new Array();for(i=0;i<N;i++) a[i]=i+1;document.write("开始的队列:<br>"); for(i=0;i<N;i++)document.write(a[i]+" ");document.write("<br>"); while(Live(a)>1){for(i=0;i<N;i++){if(a[i]!=0) n++; if(n==M) {a[i]=0;n=0;}}for(i=0;i<N;i++)document.write(a[i]+" ");document.write("<br>");}}</SCRIPT></HEAD><BODY BGCOLOR="#00FF00"><DIV><INPUT TYPE="button" ID=BUTTON1 value="点名开杀" onclick='fun()'/><INPUT TYPE="input" ID="text1" /><INPUT TYPE="input" ID="text2" /></DIV></BODY>
</HTML>
C语言画一个sin(x)的曲线
对C语言而言,如果仅仅是在命令提示符下显示结果的那种程序,要完成漂亮的图形显示,基本是不可能的事情,但计算机毕竟是从没图形的显示器开始的,所以用字符模拟个曲线也不是完全做不到。
首先是要设计一个虚拟的屏幕,这个屏幕大小假定就是AX*AY,一般的,AX不超过80,而AY可以大点,实际为了美观,AY也在40以内。AX取80的原因是:当年黑屏幕下的DOS操作系统,屏幕一行就显示80个字符,一屏幕也就40行。
所以我们在内存中先申请一个二维数组:
char s[40][80];
首先,把这个数组里全部装空格,就是:
for(I=0;I<40;I++)for(j=0;j<80;j++)s[I][j]=’ ‘;
我们要在20行上画一个X轴,就是:
n=20;
for(i=0;i<AX-1;i++)s[n][i]='-';
s[n][79]=’>’;//画个X轴的箭头
同理画Y轴,就是:
for(i=0;i<AY-1;i++)s[i][0]='|';
s[0][0]='^';//就是Y轴的箭头
因为X坐标有80个单位,要画360度的sin(x)、所以每个单位就相当于23.1416i/80,于是有:
for(i=0;i<80;i++){n=40/2;x=2*3.141592654*i/80;y=sin(x);n=n-n*y;s[n][i]='*';//画*点}
有了这个数组后,就是打印而已:
for(i=0;i<40;i++)for(j=0;j<80;j++)printf("%c",s[i][j]);
打印出的就是sin(x)的曲线。
完整的程序就是:
//显示SIN(X)的曲线
#include<stdio.h>
#include<math.h>
#define AX 80
#define AY 41
char s[AY][AX];
void cScreen()
{
int i,j,n;
for(i=0;i<AY;i++)for(j=0;j<AX;j++)s[i][j]=' ';n=AY/2;
for(i=0;i<AX-1;i++)s[n][i]='-';
s[n][AX-1]='>';s[n+1][AX-1]='X';for(i=0;i<AY-1;i++)s[i][0]='|';
s[0][0]='^';s[0][1]='Y';s[n][0]='+';s[n+1][1]='0';
}void Display()
{
int i,j;
for(i=0;i<AY;i++)for(j=0;j<AX;j++)printf("%c",s[i][j]);
}main()
{
int i,j,n;
double x,y;
cScreen();for(i=0;i<AX;i++){n=AY/2;x=2*3.141592654*i/AX;y=sin(x);n=n-n*y;s[n][i]='*';}
Display();
}
这个程序只不过把建立坐标系、显示等都分开了而已。
C语言的这个思路很重要,关键是我们设计了一个s[ ][ ]这样的数组做虚拟屏幕,而实际中,显示器的缓存就是这样的,只不过它的存储量要比s数组大的多,仅仅一个1024X768的24位显示,一屏幕需要:1024X768X3/1024(K)字节,考虑到动画的切换,目前实际一个显示卡的存储都在512M上下,就相当于s数组的大小。题目5.18同上例。
但对JavaScript而言,要这么显示sin()简直是糟蹋行当。如何产生更加美观的函数图形,我们在下一讲中介绍。
螺旋线访问二维数组
在C中构造这样的路径数组,分别按行、列组织路径。就是:
int r[]={0,1,2,3,4,4,4,4,3,2,1,1,2};
int c[]={0,0,0,0,0,1,2,3,3,3,3,2,2};
int A[5][5]={{1,16,15,14,13},{2,17,24,23,12},{3,18,25,22,11},{4,19,20,21,10},{5, 6,7,8,9}
};
int n,m;
for(I=0;I<13;I++)
{n=r[I];m=c[I];printf(“%d ”,A[n][m]);
}
自己在JavaScript里完成上述程序,应该是不难的,自己修改就是。