二、棧+進制轉換

棧是一種遵循後進先出(LIFO)原則的有序集合。新添加的或待刪除的元素都保存在棧的末尾,稱作棧頂,另一端就叫棧底。在棧裏,新元素都靠近棧頂,舊元素都接近棧底。

現實生活中有很多棧的例子,如一摞書或者餐廳裏堆放的盤子

接下來將創建一個類來表示棧,先聲明類:

function Stack() {
	/*
	 * 我們可以使用數組來保存棧裏的元素,然後聲明一些操作棧的方法:
	 * push(element):添加一個(或幾個)新元素到棧頂。
	 * pop():移除棧頂的元素,同時返回被移除的元素。
	 * peek():返回棧頂的元素,不對棧做任何修改(這個方法不會移除棧頂的元素,僅僅返回它)。
	 * isEmpty():如果棧裏沒有任何元素就返回true,否則返回false。
	 * clear():移除棧裏的所有元素。
	 * size():返回棧裏的元素個數,這個方法和數組的length屬性很類似。
	 * print():以字符串形式打印當前的數組。
	 */
	const items = [];
	this.push = function (element) {
		items.push(element);
	};
	this.pop = function () {
		return items.pop();
	};
	this.peek = function () {
		return items[items.length - 1];
	};
	this.isEmpty = function () {
		return items.length === 0;
	};
	this.clear = function () {
		items= [];
	};
	this.size = function () {
		return items.length;
	};
	this.print = function () {
		consle.log(items.toString());
	};
}

使用棧的方法前,先實例化棧:const stack = new Stack();
使用棧的push方法向棧中添加數據,形式如下圖,最先添加的元素總是位於棧底,最後添加的元素總是位於棧頂
1、stack.push(5,8);
2、stack.push(11);
3、stack.push(15);
在這裏插入圖片描述
使用棧的pop方法從棧中移除數據,形式如下圖,最先移除的元素總是位於棧頂,最後移除的元素總是位於棧底
1、stack.pop();
2、stack.pop();
在這裏插入圖片描述


實戰:使用棧的方式進行十進制轉換

一、從十進制到二進制
要把十進制轉化成二進制,我們可以將該十進制數字和2整除(二進制是滿二進一),直到結果是0爲止。舉個例子,把十進制的數字10轉化成二進制的數字,過程大概是這樣:
1、將餘數放入棧中;
2、輸出=將餘數移除;
3、十進制10=>二進制1010。
在這裏插入圖片描述

十進制轉換成二進制的算法描述如下:

/*
 * decNumber:需要轉換的進制數值。
 * remStack :棧的實例化。
 * rem:每次整除的餘數。
 * binaryString:轉化後的二進制數值。
 */
function divideBy2(decNumber) {
	const remStack = new Stack(),
	let	rem,
	let	binaryString = '';
	while (decNumber > 0) {
		rem = Math.floor(decNumber % 2);
		remStack.push(rem);
		decNumber = Math.floor(decNumber / 2);
	}
	while (!remStack.isEmpty()) {
		binaryString += remStack.pop().toString();
	}
	return binaryString;
}
console.log(divideBy2(10));  //1010

在上面這段代碼裏,當結果滿足和2做整除的條件時,我們會獲得當前結果和2的餘數,放到棧裏。然後讓結果和2做整除。另外請注意:JavaScript有數字類型,但是它不會區分究竟是整數還是浮點數因此,要使用Math.floor函數讓除法的操作僅返回整數部分。最後,用pop方法把棧中的元素都移除,把出棧的元素連接成字符串。

我們很容易修改上面的算法,使之能把十進制轉換成任何進制。除了讓十進制數字和2整除轉成二進制數,還可以傳入其他任意進制的基數爲參數,就像下面算法這樣:

/*
 * decNumber:需要轉換的進制數值。
 * base:目標進制基數。
 * remStack:棧的實例化。
 * rem:每次整除的餘數。
 * digits:顯示位數(需轉化內容)。
 * baseString:轉化後的進制數值。
 */
function baseConverter(decNumber, base) {
	const remStack = new Stack(),
	let	rem,
	let	baseString = '',
	let	digits = '0123456789ABCDEF';
	while (decNumber > 0) {
		rem = Math.floor(decNumber % base);
		remStack.push(rem);
		decNumber = Math.floor(decNumber / base);
	}
	while (!remStack.isEmpty()) {
		baseString += digits[remStack.pop()];
	}
	return baseString;
}
console.log('二進制', baseConverter(100345, 2));     //二進制 11000011111111001
console.log('八進制', baseConverter(100345, 8));     //八進制 303771
console.log('十六進制', baseConverter(100345, 16));  //十六進制 187F9

在將十進制轉成二進制時,餘數是0或1;在將十進制轉成八進制時,餘數是0到7之間的數;但是將十進制轉成16進制時,餘數是0到9之間的數字加上A、B、C、D、E和F(對應10、11、12、13、14和15)。因此,我們需要對棧中的數字做個轉化纔可以。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章