
圖說演算法使用JavaScript(八)

請設計一程式來宣告3個二維陣列,來實作2個矩陣相加的過程,並顯示兩矩陣相加後的結果。
JS matrix_add.js
var A = new Array();
var B = new Array();
var C = new Array();
for (let i=0; i<3; i++){
A[i]=new Array();
B[i]=new Array();
C[i]=new Array();
}
A= [[1,3,5],[7,9,11],[13,15,17]];
B= [[9,8,7],[6,5,4],[3,2,1]];
N=3;
for (let i=0;i<3; i++){
for (let j=0; j<3; j++){
C[i][j]=A[i][j]+B[i][j];
}
}
console.log("[矩陣A和矩陣B相加的結果]");
let str='';
for (let i=0; i<3; i++){
for (let j=0; j<3; j++){
str=str+C[i][j]+'\t';
}
str=str+'\n';
}
console.log(str);
PHP matrix_add.php
$A_arr=array(array(1,3,5),array(7,9,11),array(13,15,17));
$B_arr=array(array(9,8,7),array(6,5,4),array(3,2,1));
$C_arr=array();
for ($i=0; $i<count($A_arr); $i++){
for($j=0; $j<count($A_arr);$j++){
$C_arr[$i][$j] = $A_arr[$i][$j] + $B_arr[$i][$j];
}
}
print_r($C_arr);
echo "<br><hr><br>";
foreach ($C_arr as $item ){
echo "[";
$t=1;
foreach ($item as $value){
if($t<3) echo $value.",";
else echo $value;
$t++;
}
echo "]<br>";
}
函式說明
foreach ($arr as $yourstr){
echo $yourstr //$yourstr => $arr or $value
}
如果談到兩個矩陣A與B的相乘,是有某些條件限制。首先必須符合A為一個m*n的矩陣,B為一個n*p的矩陣,對A*B之後的結果為一個m*p的矩陣C。
請設計一程式來實作下列兩個矩陣的相乘結果。
JS matrix_multiply.js
const M=2;
const N=3;
const P=2;
A=[6,3,5,8,9,7];
B=[5,10,14,7,6,8];
C=[0,0,0,0];
if (M<=0 || N<=0 || P<=0) console.log('[錯誤:維數M,N,P必須大於0]');
for (let i=0; i<M; i++){
for (let j=0; j<P; j++){
let Temp=0;
for (let k=0; k<N; k++) Temp = Temp +parseInt(A[i*N+k])*parseInt(B[k*P+j]);
C[i*P+j] = Temp;
}
}
console.log('[AxB的結果是]');
let str='';
for (i=0; i<M; i++){
for (j=0; j<P; j++){
str = str+C[i*P+j]+ '\t';
}
str = str+'\n';
}
console.log(str);
PHP matrix_multiply.php
$a_arr = array(array(6,3,5),array(8,9,7));
$b_arr = array(array(5,10),array(14,7),array(6,8));
$a_m = count($a_arr); //陣列 M列
$a_n = count($a_arr[0]); //陣列 N行
$b_n = count($b_arr); //陣列 N列
$b_p = count($b_arr[0]); //陣列 P行
$c_arr = array();
if ($a_m <=0 || $a_n <=0 || $b_n<=0 || $b_p<=0 || $a_n!=$b_n){
echo "條件錯誤";
}
//echo "a_m=".$a_m."; a_n=".$a_n."<br>";
//echo "b_n=".$b_n."; b_p=".$b_p."<br>";
for ($i=0 ; $i<$a_m; $i++){
for ($j=0; $j<$b_p; $j++){
$temp=0;
for ($k=0 ; $k<$a_n; $k++){
$temp = $temp + intval($a_arr[$i][$k])*intval($b_arr[$k][$j]);
//echo $temp."<br>";
$c_arr[$i][$j]=$temp;
}
//echo $temp."<br>";
}
//echo "--<br>";
}
print_r($c_arr);
「轉置矩陣」At就是把原矩陣的行座標元素相互調換,假設At為A的轉置矩陣,則有At[j,i]=[i,j],如下圖所示:
範例
請設計一程式來實作一4*4二微陣列的轉置矩陣。
JS transpose.js
arrA=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
N=4;
arrB=[[],[],[],[]];
console.log('原設定的矩陣內容');
for (i=0; i<4; i++){
str = '';
for (j=0; j<4; j++){
str= str+arrA[i][j]+'\t';
}
console.log(str);
}
for(i=0; i<4; i++){
for(j=0; j<4; j++){
arrB[i][j]=arrA[j][i];
}
}
console.log('[轉置矩陣的內容為]');
for (i=0; i<4; i++){
str = '';
for (j=0; j<4; j++){
str= str+arrB[i][j]+'\t';
}
console.log(str);
}
PHP transpose.php
$a_arr = array(array(1,2,3,4),array(5,6,7,8),array(9,10,11,12),array(13,14,15,16));
$b_arr = array();
$arr_m = count($a_arr);
$arr_n = count($a_arr[0]);
echo "M-".$arr_m."N-".$arr_n."<br>";
for ($i=0; $i<$arr_m; $i++){
for($j=0; $j<$arr_n; $j++){
$b_arr[$i][$j]=$a_arr[$j][$i];
}
}
foreach($a_arr as $item){
foreach ($item as $value){
echo $value." ";
}
echo "<br>";
}
foreach($b_arr as $item){
foreach ($item as $value){
echo $value." ";
}
echo "<br>";
}
稀疏矩陣最簡單的定義就是一個矩陣中大部分的元素為0,即可稱為「稀疏矩陣」Sparse Matrix。例如下列的矩陣就是典型的稀疏矩陣。
當然如果直接使用傳統的二維陣列來儲存上圖的稀疏矩陣也是可以,但事實上許多元素都是0。這樣的做法在矩陣很大時的稀疏矩陣,就會十分浪費記憶體空間。
而改進空間的方法就是利用三項式(3-tuple)的資料結構。我們把每一個非零項目以(i,j,item-value)來表示。更詳細的形容,就是假如一個稀疏矩陣有n個非零項目,那麼可以利用一個A(0:n,1:3)的二維陣列來表示。
其中A(0,1)代表此稀疏矩陣的列數,A(0,2)代表此稀疏矩陣的行數,而A(0,3)則是此稀疏矩陣非零項目的總數。另外每一個非零項目以(i,j,item-value)來表示。其中i為此非零項目所在的列數,j為此非零項目所在行數,item-value則此分零項的值。以上圖6*6稀疏矩陣為例,則可以以下表示:
A(0,1)=>表示此舉矩陣的列數。
A(0,2)=>表示此舉矩陣的行數。
A(0,3)=>表示此舉矩陣非零項目的總數。
這種利用3項式(3-tuple)資料結構來壓縮稀疏矩陣,可以減少記憶體不必要的浪費。
對於給定數量的級別,請用$和符號空格打輸出類似「階梯狀」的圖形外觀。
JS staircase.js
const draw = no => {
let pictures = "";
for (let row=0; row<no; row++){
str="";
for (let column = 0; column<no; column++)
str += column <= row? "$":" ";
pictures +=str + "\n";
}
return pictures;
};
console.log(draw(15));
PHP staircase.php
$my_num = 15;
function pictures($n){
for($i=0; $i<$n; $i++){
if($i!=0) echo "<br>";
for ($j=0; $j<=$i; $j++){
echo "$";
}
}
}
$pictures = pictures($my_num);
對於給定數量的級別,請使用$和符號空格打輸出類似「金字塔」的圖形外觀。
課本的JS範例是錯的
我解的是對的↓
PHP pyramid.php
$my_num = 15;
//function pictures($n){
$layer = $my_num; //幾層
$num = $my_num*2-1; //個數
$mid = $layer ; //中間數
for($h=1; $h<=$layer; $h++){
for($j=$mid-$h; $j>=1; $j--){
echo " ";
}
for($i=1; $i<=$h*2-1; $i++){
echo "$";
}
echo "<br>";
}
echo "<br>".$layer."-".$num."-".$mid;
「物件」指的就是物件。恩,但其實有很多東西本身也算是物件,例如陣列和函式,不相信嗎?讓我們繼續看下去。你可以在JavaScript裡面宣告一個陣列,然後用typeof去得到這個陣列的型別,就可以看出一些端倪:
JavaScript提供了Array這個所有地方都可以使用全域物件,而在這個Array.isArray的方法能夠讓我們使用,來知道某數值是不是一個陣列。
好,那麼剛剛說函式也是物件型別,是這樣嗎?你會發現,當你一樣用typeof去觀察一個function的型別時,所得到的結果不是object,而是function。
先別急著反駁,讓我先用一個最簡單的方式證明你看。前面應該提到過,一個物件型別的數值,可以用.或是[]來做存取。那麼首先我宣告一個函式,並把這個函式當作物件使用,在上面新增一個屬性之後,再取出這個屬性來看看,是不是得到同樣的值:
函式真的是像物件一樣的東西,事實上,它真的就是。在JavaScript裡面,函式算是一個比較物件,稱為「函式物件」(Function Object),它除了可以被當作函式來呼叫,也能夠當作物件使用。
當我們說一個語言具有一級函式的特性時,代表這個語言把函式當作變數值一樣看待,也因此可以把函式當作參數一樣傳入另外一個函式裡面,也能夠以函式作為另一個函式的回傳值。在Function Programing 裡面,也是因為這個特性,才有辦法做到複合函式(Function Composition)。
在JavaScript內,函式本身也是一個特殊的物件(就是函式物件),所以才有辦法把函式當作參數傳給另外一個函式來做使用。
給定一系列股票價格,找出產生最大利潤的最小買入價和最大賣出價。舉例以陣列的方式提供一系列的股票價格,例如[24,27,32,36,45],這個函數會找出這一系列的股票價格的最低買入價及最高賣出價,再以陣列的方式回傳,如此一來可以計算出這支股票的最大利潤。
JS max_prifit.js
var maxProfit=(prices)=> {
let low = prices[0] < prices[1]? prices[0]:prices[1];
high = prices[0] < prices[1] ? prices[1]:prices[2];
let maxProfit = high - low;
let temp = low;
for (let index = 2; index < prices.length; index++){
const sellPrice = prices[index];
if (low > sellPrice) temp = prices[index];
else{
const profit = sellPrice - low;
if (profit > maxProfit)
(maxProfit = profit),
(high = sellPrice),
(low = temp);
}
}
return [low, high];
}
console.log("產生最大歷潤的最小買入價和最大賣出價分別為:");
console.log(maxProfit([24,27,32,36,45]));
PHP max_profit.php
$arr= array (24,27,32,36,45);
function get_max_profit($arr){
$low = ($arr[0] < $arr[1]) ? $arr[0] : $arr [1];
$high = ($arr[0] > $arr[1]) ? $arr[0] : $arr[1];
$maxProfit = $high - $low;
$temp = $low;
$len = count($arr);
$ans = array();
$i=1;
while ( $i <= $len-1){
$sellPrice = $arr[$i];
if($low > $sellPrice) $temp = $arr[$i];
else {
$profit = $sellPrice -$low;
if($profit > $maxProfit){
$maxProfit = $profit;
$high = $sellPrice;
$low = $temp;
}
}
$i++;
}
$ans[] =array($low,$high);
return $ans;
}
$my_max_profix = get_max_profit($arr);
print_r($my_max_profix);
JS fibonacci.js
var fib=(n)=>{
if (n==0){
return 0;
} else if (n==1 || n==2){
return 1;
} else{
return (fib(n-1)+fib(n-2));
}
}
const num=10;
for(i=0; i<=num; i++){
console.log("fib("+i+")=" + fib(i));
}
PHP fibonacci.php
$my_num = 30; //超過38時,執行會超過30秒
function my_fibnacci ($n){
switch ($n) {
case ($n==0):
return 0;
break;
case ($n==1 ||$n==2):
return 1;
break;
default:
return(my_fibnacci($n-1)+my_fibnacci($n-2));
break;
}
}
for ($i=0 ; $i<=$my_num; $i++){
echo "fib(".$i.")=".my_fibnacci($i)."<br>";
}
這是一種具有記憶性質的費伯納序列的做法,它可以使得在求取費伯納序列能以較高的效率取得。也就是動態規劃法,它是一種具備記憶體功能的演算法。
JS momoized_fibonacci.js
output =[]; //宣告陣列
var fib=(n)=>{
if (n==0) return 0;
if (n==1 ) return 1;
else{
output[0]=0;
output[1]=1;
for (t=2; t<=n; t++){
output[t]=output[t-1]+output[t-2];
}
return output[n];
}
}
const num=9;
for(i=0; i<=num; i++){
console.log("fib("+i+")=" + fib(i));
}
PHP memoize_fibonacci.php
$my_num = 50;
function my_fibnacci ($n){
$ans=array();
if($n==0) return 0;
if($n==1) return 1;
else{
$ans[0]=0;
$ans[1]=1;
for ($j=2; $j<=$n; $j++){
$ans[$j]=$ans[$j-1]+$ans[$j-2];
}
return $ans[$n];
}
}
for ($i=0 ; $i<=$my_num; $i++){
echo "fib(".$i.")=".my_fibnacci($i)."<br>";
}
物件是JavaScript 裡面很重要的型別,在其他語言裡的物件可能有不一樣的意思,但在JavaScript裡面,物件就是「一連串鍵與值配對(key-value pairs)的組合」。換句話說,這意味著物件是由一個個的名稱與一個個的對應內容聚集在一起後形成的結果,這個物件的鍵名又被稱為物件的屬性(property),屬性的用途跟變數有一點相像,都是讓開發者在存取時有一個獨特的名稱,用以區別不同內容。
一個物件最簡單的宣告方式,就是在賦予變數時,用兩個大括號,將即將宣告的物件包裹起來,並用冒號來區分物件內的屬性名稱與想要存放的數值內容。範例如下:
一般的變數在宣告並被賦值後,我們就用該變數名稱來表示要存取對應內容。而這個變數如果存取的內容是物件,則可以搭配中括號「[]」,或是小數點符號「.」來拿到物件裡面某個屬性的內容:
anObject["key1"] --> 用中括號來存取物件屬性的內容
abObject.key1 --> 用小數點符號來存取物件屬性的內容
陣列在許多程式語言都會出現。它跟物件有一點點像,但是使用的方式有些差異。如同前面提到的,如果物件是一連串的名稱與對應內容組合而成的型別,那麼陣列就是「把一系列的數值放在一起形成的組合」。意即可以先把陣列看成沒有屬性的物件,只是陣列並非像物件那樣是用大括號來宣告。
使用中括號就能簡單宣告出一個陣列,並在中括號內用逗點區隔想要存放的各個值,與物件一樣,陣列可以存放多於一個以上的數值。
var array = ["內容一", "內容二"];
與物件屬性可以存放的內容相同,對於陣列裡面可以存放的內容,沒有型別上的限制,想要在陣列裡面放數字、字串、布林、物件或甚至是另外一個陣列,都是可以的。通常存放陣列裡面的數值,我們會用「元素」(element)來稱呼。
存取陣列元素的方法跟物件一樣,可以使用中括號來表示。但是陣列不像物件那樣有明確的屬性可以知道要對哪一個內容作存取,該可麼辦呢?在陣列裡面的處理方式是,既然沒有明確的名稱,那麼就從第一個元素開始,給每一個元素一個足以區別內容的號碼,我們稱之為「索引」(index),陣列的這個號碼,是從0開始算的。
陣列元素的長度可以用.length來取得,它的用法就跟存取物件屬性一模一樣。事實上,陣列背後的實作也是以物件來達成,只是使用的方式不一樣而已。
var array = ["1", "2", "3"];
console.log(array.length); //3
函式最簡單的使用方式是透過function這個關鍵字來告訴JavaScript你想要宣告的函式。與變數一樣,函式在一般情況下也必須具有名稱才能讓JavaScript知道你想呼叫(執行)哪一個函式。
至於函式執行後回傳的結果則透過return來決定要回傳內容是什麼,而就像前面提到的一樣,return不一定要存在於函式的內容中,只不過如果在函式內沒有任何return被使用,或是有return但後面沒有任何要回傳的值,JavaScript都會自動幫你將回傳的值設置為undefined,所以可以把一個函式回傳的預設值當作是undefined。
ES6出現了兩個新的變數宣告的關鍵字,也是目前實際產品開發中最常使用到的兩個語法,它們分別是let以及const。在前面則是用var來處理。
let其實與var差不多,與var不同是宣告變數的範疇、以及不能被重複宣告。 var是函式範疇,而let是區塊範疇
區塊範疇相比於var的函式範疇,究竟有什麼優缺點呢?一個很明顯的好處就是,能夠更有效避免變數意外地被修改或覆蓋。
當我在全域宣告一個變數i,並在後面使用了for迴圈,for迴圈裡面的條件判斷也用到另外一個新的宣告的i,但是你會發現在for條件判斷用i其實在迴圈進行時也無意間對外面的全域變數進行了修改,最後,外面的變數i的內容就跟著變成10。而若使用const和let,這個問題就不會發生。
const和let的範疇則是一樣的,那麼const和let相較起來又有什麼差異呢?
const這個字本身意味著常數。它的範疇與let相同,都屬於區塊範疇,但是與let布一樣的是,使用const宣告變數在第一次宣告,並被指派後,就不能修改。也就是說,使用const所宣告的變數,只能夠被讀取。
使用const宣告變數時,一定要跟著一起指派內容。它與var或let不一樣,可以指宣告變數名稱而不給值。若你使用const時這麼做的話,就會出現錯誤。
而上面講到const所宣告的變數無法再重新指派的規則,其實有一個看起來像是例外的情況,那就是當const與物件、陣列一起使用時,會有這樣的情形發生:
看到了嗎?使用const所宣告的變數內容若是物件,則該物件裡的屬性還是能夠被存取跟修改,這看來很像是在對該變數內容作修改,其實並沒有。當變數被宣告並且存放的數值是一個物件時,所帶給變數的並不是物件本身的內容,而是物件存放的記憶體位置。
所以只要該變數所參考的記憶體位置保持一致,就不會有問題。而換另外一個角度來看,若我重新對const所宣告的變數指派另一個物件,那是會報錯的。
給定一個短句,將句子中的每一個單字的字母順序反轉,請注意,是句子中的每個單字,以字做為單位進行字母順序反轉。
JS reverse_word.js
const change = str =>{
const answer = [];
str.split(" ").forEach(word =>{ //注意""有空格
let temp = ""; //注意""沒空格
for(let i = word.length-1; i>=0; i--){
temp +=word[i];
}
answer.push(temp);
});
return answer.join(" "); //注意""有空格
};
console.log("原來句子:");
console.log("The greatest test of courage on earth is to bear defeat without losing heart.");
console.log("句子中每個單字都反轉:");
console.log(change("The greatest test of courage on earth is to bear defeat without losing heart."));
PHP reverse_word.php
$my_str="The greatest test of courage on earth is to bear defeat without losing heart.";
function my_reverse ($str){
$my_arr = explode(" ", $str);
$len = count($my_arr);
$i = 0;
while ($i<=$len-1){
$t_str[]=strrev($my_arr[$i]);
$i++;
}
$my_re=join(" ",$t_str);
return $my_re;
}
$my_re = my_reverse($my_str);
echo $my_str."<br>";
echo $my_re;
使用函數:
explode()
count()
join() 或 implode() 把陣列元素组合成的字符串。
strre() 反轉字串
給定一個短句,將句子中的每一個單字的第一個字母轉為大寫,請注意,是每句子中的每一個單字,以字做為單位進行首字大寫轉換。
JS capitalization.htm
const bigletter = sentence => {
const words = []; //宣告words陣列
for (let word of sentence.split(""))
words.push(word[0].toUpperCase() + word.slice(1));
return words.join("");
};
console.log("原來的句子");
console.log("Genius is an infinite capacity for taking pains.");
console.log("首字大寫的句子:");
console.log(bigletter("Genius is an infinite capacity for taking pains."));
PHP capitalization.php
$my_str="Genius is an infinite capacity for taking pains.";
function my_bigletter ($str){
$my_arr = explode(" ",$str);
$my_len = count($my_arr);
$t_big = array();
$i = 0;
while ($i<=$my_len-1){
array_push($t_big, ucfirst($my_arr[$i]));
$i++;
}
$f_big = implode(" ", $t_big);
return $f_big;
}
$f_bigletter=my_bigletter($my_str);
echo $f_bigletter;
使用函數
explode()
count()
array_push() 将一个或多个元素插入陣列的尾端
implode()
給定一個數字組,計算平均值,例如給定的陣列[1,2,3],則回傳平均值為2.0。這支程式可以利用Javascript的reduce()方法,它能將陣列中每項元素(由左至右)傳入回呼函式,將陣列化為單一值。
JS mean.js
const stat1 = [2,8,7,6,5,6,4];
const stat2 = [9,2,8,7,6,5,6,4];
const reducer = (accu, currentValue) => accu + currentValue;
//2,8,7,6,5,6,4
console.log("第1組原始資料");
console.log("[2,8,7,6,5,6,4]");
console.log(stat1.reduce(reducer)/stat1.length);
//9,2,8,7,6,5,6,4
console.log("第2組原始資料");
console.log("[9,2,8,7,6,5,6,4]");
console.log(stat2.reduce(reducer)/stat2.length);
PHP mean.php
$my_arr_1=array(2,8,7,6,5,6,4);
$my_arr_2=array(9,2,8,7,6,5,6,4);
echo "數字陣列1:";
print_r($my_arr_1);
echo "<br>";
echo "數字陣列2:";
print_r($my_arr_2);
echo "<br>";
function get_mean ($my_arr){$len = count($my_arr);$total = array_sum($my_arr);
$mean = $total/$len;return $mean;
}
$my_mean_1 = get_mean($my_arr_1);
$my_mean_2 = get_mean($my_arr_2);
echo "my_mean_1=".$my_mean_1."<br>";
echo "my_mean_2=".$my_mean_2."<br>";
使用函數
count()
array_sum() 計算陣列元素值的總和
這個函數會傳入兩個引數,第一個引數是一個包含多個數字的整數值,第二個引數為給定的總和值(sum),該函數會回傳所有加總起來會等於給定總和的所有數值序對,這個數值序對內的數字可以多次使用。例如給定的第一個引數為[1,2,2,3,4],給定的第二個引數為數值4,則陣列中的3及1加總結果為4。另一種狀況,陣列中的2及2加總結果為4,則回傳的結果值為[[2,2],[3,1]]。
JS two_sum.js
const twototal = (num, total) =>{
const subpair = [];
const ans = [];
for (let a of num) {
const b = total -a;
if (ans.indexOf(b) !== -1){
subpair.push([a,b]);
}
ans.push(a);
}
return subpair;
}
console.log ("第1組原始資料");
console.log ("twototal([1,2,2,3,4], 4)=");
console.log (twototal([1,2,2,3,4], 4));
console.log ("第2組原始資料");
console.log ("twototal([2,3,5,1,5,1,3,4], 6)=");
console.log (twototal([2,3,5,1,5,3,4], 6));
Array.prototype.indexOf() 找出元素索引值的陣列indexOf()
Array.prototype.push() 會將一或多個的值,加入至一個陣列中
PHP two_sum.php
$arr_1 =array (2,3,5,1,5,1,3,4);
function get_two_sum($arr, $num){
$t_arr = array();
$ans = array();
$len = count($arr);
$i=0;
while ($i <=$len-1){
$b = $num - $arr[$i];
$arr_slice = array_slice($arr, $i+1);
if (in_array($b, $arr_slice) == true){
$ans[]=array($arr[$i], $b);
}
$i++;
}
return $ans;
}
$my_two_sum = get_two_sum($arr_1, 6);
print_r($my_two_sum);
使用函數
count()
arr_slice($arr,$num) 函數切割 $arr陣列、$num從多少開始切
in_array($val,$arr) 在函數中尋找是否有值
撰寫一個函數,傳入引數為一個字串,其輸出的結果會將該字串中出現頻率最高的字母輸出。
JS max_character.htm
const my_max = str =>{
const words = {}; //You can create a const object
for (let ch of str)
words[ch] = words[ch]+1 || 1;
let counter = 0;
let most = null;
for (let ch in words) {
if (words[ch] > counter){
counter = words[ch];
most = ch;
}
}
return most;
};
console.log(my_max("tomorrow"));
PHP max_character.php
//$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
$my_str="Hello World! 你好世界!";
//$my_str="我為人人,人人為我";
//$my_str="gooddoog";
echo "原來的字串:".$my_str."<br>";
function mb_str_split($str){
//不分中英字串都可以切成陣列
return preg_split('/(?<!^)(?!$)/u',$str);
}
function get_most_str($str){
$arr = mb_str_split($str); //切字串成陣列
$len = count ($arr);
$my_count = 0;
for ($i=0 ; $i<=$len-1; $i++){
$str_count=substr_count($str,$arr[$i]);
//計算出現次數
if ($str_count>$my_count){
$my_count=$str_count;
$most = $arr[$i];
}
}
return [$most,$my_count];
}
$most_str= get_most_str($my_str);
echo "最大數為".$most_str[0]."=".$most_str[1]."<br>";
使用函數:
substr_count() 計算子字串在字串中出現的次數
這個函數的功能是給定兩個包含相同數量的字母的單字或片語,並進行判斷所傳入的單字或片語是否相同的檢查函數。
JS anagrams.js
const compare = str =>{
const table ={}; //宣告一個table物件
for (let char of str.replace(/\w/g, "").toLowerCase())
table[char] = table[char]+1 || 1;
return table;
};
const anagrams = (strA, strB) =>{
const charA = compare(strA);
const charB = compare(strB);
if (Object.keys(charA).length !==Object.keys(charB).length)
return false;
for (let char in charA)
if (charA[char] !== charB[char]) return false;
return true;
};
console.log(anagrams("happy birthday", "happy birthday"));
console.log(anagrams("happyy birthday", "hhappy birthday"));
說明:
str.replace(/\w/g,"").toLowerCase();
\w 包含數字字母與底線,等同於[A-Za-z0-9_] 出處
PHP anagrams.php
$my_str_1="happy birthday";
//$my_str_1="大家好";
$my_str_2="hhhappybirthday";
//$my_str_2="happy birthday";
echo "字串_1:".$my_str_1."<br>";
echo "字串_2:".$my_str_2."<br>";
function mb_str_split($str){
//不分中英字串都可以切成陣列
return preg_split('/(?<!^)(?!$)/u',$str);
}
/*
$str_1_ar = mb_str_split($my_str_1);
$str_2_ar = mb_str_split($my_str_2);
$str_len_1 = count ($str_1_ar);
$str_len_2 = count ($str_2_ar);
$flag =($str_len_1 != $str_len_2) ;
$i=0;
if($flag==1){
echo "這兩個長度不同<br>";
}else{
while ($i<= $str_len_1-1){
$flag2=strcmp($str_1_ar[$i],$str_2_ar[$i]);
if($flag2==1){
echo "這兩個字母不同<br>";
break;
}
$i++;
}
}
*/
function my_anagrams ($str1, $str2){
$str_1_ar = mb_str_split($str1);
$str_2_ar = mb_str_split($str2);
$str_len_1 = count ($str_1_ar);
$str_len_2 = count ($str_2_ar);
$flag1 =($str_len_1 != $str_len_2) ;
$i=0;
$msg1="這兩個長度相同<br>";
$msg2="這兩個字母相同<br>";
if($flag1==1){
$msg1="這兩個長度不同<br>";
$msg2="這兩個字母不同<br>";
}
else{
while ($i<= $str_len_1-1){
$flag2=strcmp($str_1_ar[$i],$str_2_ar[$i]);
if($flag2==1){
$msg2="這兩個字母不同<br>";
}
$i++;
}//while
}//elseif
return [$msg1,$msg2];
}//function
$my_msg = my_anagrams($my_str_1,$my_str_2);
echo $my_msg[0];
echo $my_msg[1];
函數使用:
strcmp(str1,str2) 比較兩個字串(對大小寫敏感)
將給定的陣列中的元素,由前往後排列方式,變更成由後往前的排列順序。例如給定原陣列的內容值為[1,2,3,4],則所撰寫的這個函數會回傳[4,3,2,1]‵.
JS reverse.js
const rev1 = dim =>{
for (let i=0; i <dim.length /2; i++){
const temp = dim[i];
dim[i] = dim[dim.length-1-i];
dim[dim.length-1-i]=temp;
}
return dim;
};
const rev2 = dim =>{
for (let i=0; i<dim.length/2; i++) {
[dim[i], dim[dim.length-1-i]] = [
dim[dim.length-1-i], dim[i]
];
}
return dim;
};
console.log("['a','e','i','o','u']反向陣列:",rev1(['a','e','i','o','u']));
console.log("[2,4,6,8,10]反向陣列:",rev2([2,4,6,8,10]));
$my_arr_1=array("a","e","i","o","u");
$my_arr_2=array(2,4,6,8,10);
//$my_str_2="happy birthday";
echo "陣列_1:";
print_r($my_arr_1);
echo "<br>";
echo "陣列_2:";
print_r($my_arr_2);
$re_arr_1 = array_reverse($my_arr_1);
$re_arr_2 = array_reverse($my_arr_2);
echo "<br>";
echo "反陣列_1:";
print_r($re_arr_1);
echo "<br>";
echo "反陣列_2:";
print_r($re_arr_2);
函數使用:
array_reverse($arr) 以相反的順序傳回數組
撰寫一個函數,傳入的引數為一個字串,其輸出結果會將該字串以反轉的方式輸出。
JS String_Reversal.js
const reverse1 = str =>
str
.split("")
.reverse()
.join("")
const reverse2 = str =>{
let result = "";
for (let ch of str) result = ch +result;
return result;
};
console.log(reverse1("不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。"));
console.log(reverse2("一個人年輕的時候,不會思索,他將一事無成。"))
PHP String_Reversal.php
$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
echo "原來的字串:".$my_str."<br>";
function my_reverse ($str){
$len = strlen($str);
$str_ar = str_split($str);
$str_ar = array_reverse($str_ar);
$str_ar = join($str_ar);
//echo $len;
return $str_ar;
}
$my_len=my_reverse($my_str);
$my_len = strrev($my_str);
//這兩個方法,中文反轉後都會出現亂碼。
使用函數
strlen($str) 傳回字串的長度
array_reverse($arr) 以相反的順序傳回陣列
join() 把陣列組合為一個字串
strrev 反轉字串
PHP 中文字串反轉會出現亂碼,需要做以下的判斷。
所謂迴文是指由左唸到右或由又唸到左,字母排列順序都一樣的,例如以下的字串就是一個迴文:
"人人愛我!我愛人人"
JS palindrome.js
const isPalindrome = str =>
str
.split("")
.every((ch,index) => ch === str[str.length - 1 - index]);
console.log("[人人愛我!我愛人人] 這句話是否為迴文(palindrome)?",
isPalindrome("人人愛我!我愛人人"));
PHP palindrome.php
$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
//$my_str="Hello World! 你好世界!";
//$my_str="我為人人,人人為我";
//$my_str="gooddoog";
echo "原來的字串:".$my_str."<br>";
function mb_str_split($str){
//不分中英字串都可以切成陣列
return preg_split('/(?<!^)(?!$)/u',$str);
}
$arr = mb_str_split($my_str);
print_r ($arr);
$len = count($arr); //計算字串數
$mid_len=floor($len/2); //取中間整數
echo "<br>-----<br>";
for ($i=0; $i<=$mid_len-1; $i++){
if($i==0)
$last=$len-1; //第一筆 頭-尾
else
$last=$len-1-$i;
//比對兩個字是否一樣,一樣就為0
$check_f = strcmp($arr[$i],$arr[$last]);
echo $arr[$i]."-".$arr[$last]."<br>";
if ($check_f ==0){
$flag="true";
continue;
}else{
$flag="false";
//break;
}
}
echo "<br>".$len."-".$mid_len."<br>";
echo "FLAG=".$flag;
?>
使用函數:
count() 傳回陣列中元素的數目
floor() 取中間整數
strcmp 比較兩個字串(對大小寫敏感)
整數反轉的函數是只給定一個整數的引數,該函數會反轉該數字的順序。例如,原傳入字串為「12345」,則其輸入結果為「54321」。
JS inter_reversal.js
const rev = integer =>
Math.sign(integer)*parseInt(
integer
.toString()
.split("")
.reverse()
.join("")
);
console.log(rev(98754321));
console.log(rev(-987001200));
PHP integer_reversal.php
$my_int=-987001200;
//$my_int=987654321;
//print_r(str_split($my_int));
echo "原始的數字=".$my_int;
function integer_reversal ($int){
$minus=0;
$arr=str_split(strval($int));
$len = count($arr)-1;
//echo "<br>".$len;
for($i=$len; $i>=0; $i--){
if($arr[$i]=="-")
$minus=1; //偵測是否為負數
else
$re_arr[]=$arr[$i];
}
return [$re_arr,$minus]; //返回兩個數值
}
$my_re=integer_reversal($my_int);
echo "<br>";
$num=intval(join($my_re[0]));
if ($my_re[1]==1)
$num=$num*(-1);
echo "<br>反轉後數字=".$num;
使用函數:
strval() 函數用於取得變數的字串值