文章目錄
- 設計一個數組輸入并顯示的程序。
- 數組輸入和顯示
- 選擇排序
- 選擇排序
- 排序程序包
- 排序網頁
- 楊輝三角形
- 楊輝三角形網頁
- 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里完成上述程序,應該是不難的,自己修改就是。