JavaScript算法練習:字符串反轉

2021-02-19 野狗


今天在freeCodeCamp上面刷題,碰到一題是有關於字符串反轉。反轉一個字符串是JavaScript中常見的面試題之一。可能面試官會給你一個字符串「Hello Word!」,讓你通過JavaScript的方法,將其變成"!droW olleH"。

我也是初學者,利用前面所學數組相關的知識以及題目的提示,我算是過關了,後來想,是不是還有其他的方法能破此題呢?搜索了一下,還是有不少的方法,這裡把這些方法羅列一下,以備後面可以使用。

要做的事情

我們要做的事情:

將提供的字符串反向顯示

在反向字符串之前,需要將字符串轉化成一個數組

最終結果依舊是一個字符串

接下來,我們一起看看有哪些方法能實現上述要求。

使用內置函數

在練習題中,提示我們可以使用三種方法配合,能順利讓一個字符串反向顯示:

簡單的過一下:

split()方法將一個字符串對象的每個字符拆出來,並且將每個字符串當成數組的每個元素

reverse()方法用來改變數組,將數組中的元素倒個序排列,第一個數組元素成為最後一個,最後一個變成第一個

join()方法將數組中的所有元素邊接成一個字符串

來看個實例:

function reverseString(str) {

    // 第一步,使用split()方法,返回一個新數組

    // var splitString = "hello".split("");

    var splitString = str.split(""); //將字符串拆分

    // 返回一個新數組["h", "e", "l", "l", "o"]

    // 第二步,使用reverse()方法創建一個新數組

    // var reverseArray = ["h", "e", "l", "l", "o"].reverse();

    var reverseArray = splitString.reverse(); 

    // 原數組元素順序反轉["o", "l", "l", "e", "h"]

    // 第三步,使用join()方法將數組的每個元素連接在一起,組合成一個新字符串

    // var joinArray = ["o", "l", "l", "e", "h"].join("");

    var joinArray = reverseArray.join(""); 

    // "olleh"

    // 第四步,返回一個反轉的新字符串

    return joinArray; // "olleh"

}

reverseString("hello"); // => olleh

將上面的方法簡化一下,可以寫成這樣:

function reverseString(str) {

    return str.split("").reverse().join("");

}

reverseString("hello"); // => olleh

使用一個遞減循環遍歷將字符串反轉

這種方法使用的是一個for循環給原字符串做一個遞減遍歷,然後將遍歷的字符串重新合併成一個新字符串:

function reverseString(str) {

    // 第一步:創建一個空的字符串用來存儲新創建的字符串

    var newString = "";

    // 第二步:使用for循環

    // 循環從str.length-1開始做遞減遍歷,直到 i 大於或等於0,循環將繼續

    // str.length - 1對應的就是字符串最後一個字符o

    for (var i = str.length - 1; i >= 0; i--) { 

        newString += str[i]; // 或者 newString = newString + str[i];

    }

    // 第三步:返回反轉的字符串

    return newString; 

}

reverseString('hello'); // => // "olleh"

簡單的看看字符串遍歷的過程。假設需要將字符串"hello"反轉。其整個遍歷過程如下表所示:

迭代順序對應i的值新字符串 newString每次迭代str.length - 1newString + str[i]第一次迭代5 - 1 = 4"" + "o" = "o"第二次迭代4 - 1 = 3"o" + "l" = "ol"第三次迭代3 - 1 = 2"ol" + "l" = "oll"第四次迭代2 - 1 = 1"oll" + "e" = "olle"第五次迭代1 - 1 = 0"olle" + "h" = "olleh"

其實上面的for循環,也可以換成while循環:

function reverseString (str) {

    var newString = '';

    var i = str.length;

    while (i > 0) {

        newString += str.substring(i - 1, i);

        i--;

    }

    return newString;

}

reverseString("hello"); // => olleh

在while循環中substring()方法。substring() 返回字符串兩個索引之間(或到字符串末尾)的子串。

使用遞歸實現字符串反向

使用String.prototype.substr()和String.prototype.charAt()方法也可以將一個字符串反向。

substr() 方法返回字符串中從指定位置開始到指定長度的子字符串。比如:

var str = "abcdefghij";

console.log("(1,2): "    + str.substr(1,2));   // (1,2): bc

console.log("(-3,2): "   + str.substr(-3,2));  // (-3,2): hi

console.log("(-3): "     + str.substr(-3));    // (-3): hij

console.log("(1): "      + str.substr(1));     // (1): bcdefghij

console.log("(-20, 2): " + str.substr(-20,2)); // (-20, 2): ab

console.log("(20, 2): "  + str.substr(20,2));  // (20, 2):

charAt() 方法返回字符串中指定位置的字符。字符串中的字符從左向右索引,第一個字符的索引值為 0,最後一個字符(假設該字符位於字符串 stringName 中)的索引值為 stringName.length - 1。 如果指定的 index 值超出了該範圍,則返回一個空字符串。

var anyString = "Brave new world";

console.log("The character at index 0   is '" + anyString.charAt(0)   + "'"); // =>The character at index 0 is 'B'

console.log("The character at index 1   is '" + anyString.charAt(1)   + "'"); // =>The character at index 1 is 'r'

console.log("The character at index 2   is '" + anyString.charAt(2)   + "'"); // =>The character at index 2 is 'a'

console.log("The character at index 3   is '" + anyString.charAt(3)   + "'"); // => The character at index 3 is 'v'

console.log("The character at index 4   is '" + anyString.charAt(4)   + "'"); // => The character at index 4 is 'e'

console.log("The character at index 999 is '" + anyString.charAt(999) + "'"); // => The character at index 999 is ''

結合起來,我們可以這樣做實現字符串反向:

function reverseString(str) {

    if (str === "") {

        return "";

    } else {

        return reverseString(str.substr(1)) + str.charAt(0);

    }

}

reverseString("hello"); // => olleh

第一部分的遞歸方法。你需要記住,你不會只調用一次,你將會有幾個嵌套的調用。

每次調用str === "?"reverseString(str.subst(1))+ str.charAt(0)第一次調用reverseString("Hello")reverseString("ello") + "h"第二次調用reverseString("ello")reverseString("llo") + "e"第三次調用reverseString("llo")reverseString("lo") + "l"第四次調用reverseString("lo")reverseString("o") + "l"第五次調用reverseString("o")reverseString("") + "o"

第二部分的遞歸方法。

每次調用返回第五次調用reverseString("") + "o" = "o"第四次調用reverseString("o") + "l" = "o" + "l"第三次調用reverseString("lo") + "l" = "o" + "l" + "l"第二次調用reverserString("llo") + "e" = "o" + "l" + "l" + "e"第一次調用reverserString("ello") + "h" = "o" + "l" + "l" + "e" + "h"

上面的方法還可以繼續改良一下,改成三元操作符:

function reverseString(str) {

    return (str === '') ? '' : reverseString(str.substr(1)) + str.charAt(0);

}

reverseString("hello"); // => olleh

還可以換成這樣的方式

function reverseString(str) {

  return str && reverseString(str.substr(1)) + str[0];

}

reverseString("hello"); // => olleh

其他方法

除了上面的方法之外,其實還有其他一些方法:

方法一

function reverseString (str) {

    var newString = [];

    for (var i = str.length - 1, j = 0; i >= 0; i--, j++) {

        newString[j] = str[i];

    }

    return newString.join('');

}

reverseString("hello"); // => olleh

方法二

function reverseString (str) {

    for (var i = str.length - 1, newString = ''; i >= 0; newString += str[i--] ) {

    }

    return newString;

}

reverseString("hello"); // => olleh

方法三

function reverseString (str) {

    function rev(str, len, newString) {

        return (len === 0) ? newString : rev(str, --len, (newString += str[len]));

    }

    return rev(str, str.length, '');

}

reverseString("hello"); // =>olleh

方法四

function reverseString (str) {

    str = str.split('');

    var len = str.length,

        halfIndex = Math.floor(len / 2) - 1,

        newString;

    for (var i = 0; i <= halfIndex; i++) {

        newString = str[len - i - 1];

        str[len - i - 1] = str[i];

        str[i] = newString;

    }

    return str.join('');

}

reverseString("hello"); // => olleh

方法五

function reverseString (str) {

    if (str.length < 2) {

        return str;

    }

    var halfIndex = Math.ceil(str.length / 2);

    return reverseString(str.substr(halfIndex)) + reverseString(str.substr(0, halfIndex));

}

reverseString("hello"); // =>olleh

方法六

function reverseString(str) {

  return [].reduceRight.call(str, function(prev, curr) {

    return prev + curr;

  }, '');

}

reverseString("hello"); // =>olleh

ES6的方法

在ES6中,可以變得更為簡單一些,如:

[...str].reverse().join('');

或者:

[...str].reduceRight( (prev, curr) => prev + curr );

或者:

const reverse = str =>

  str && reverse(str.substr(1)) + str[0];

結論

字符串反轉是一個小而簡單的算法,前面也說了,常被用來面試JavaScript基礎。你可以使用上面各種方法來解決這個問題,甚至使用更為複雜的解決方案。如果你有更好的方法,歡迎在下面的評論中補上,與我們一起分享。


原文:http://www.w3cplus.com/javascript/how-to-reverse-a-string-in-javascript-in-different-ways.html


這裡,了解野狗!

相關焦點

  • 20個常用的JavaScript字符串方法
    concat() 方法用於連接兩個或多個字符串,此方法不改變現有的字符串,返回拼接後的新的字符串。//concat(v1, v2,..) var message="Sam" var final=message.concat(" is a"," hopeless romantic.")
  • 華為算法面試經典題目,五種字符串操作算法,快來收藏
    上次和大家分享了我總結的一些基礎的華為算法面試題,今天我又整理了一份華為算法面試題中的字符串操作算法的題目和大家一起分享。喜歡的小夥伴趕緊收藏吧。題目一:字符串個數統計字符串個數統計一個很常用的算法。在字符串操作算法中,屬於一個比較簡單一些的算法題。但是如果進行擴展的話,還是可以難倒一大部分人的。下面開始看題目。題目:編寫一個函數,計算字符串中含有的不同字符的個數。
  • Javascript去除字符串中的點或其他符號
    在前端上使用javascript進行操作的。測試了兩次沒有好用,程序直接把整個字符串都進行了替換,在考慮這個是為什麼呢?javascript(請忽略此配圖)示例var ip = data.field.ip.replace(/.
  • 在JavaScript中,使用replace()、test()和exec()方法匹配字符串
    JavaScript核心代碼如下:<script type="text/javascript">var str = "Hello Microsoft!",這個字符串是「案例」。將上面的核心代碼,運行一下結果:圖2對於replace()方法,返回的是替換後的整個字符串,也是需要的有意義的字符串。
  • JavaScript中的算法(附10道面試常見算法題解決方法和思路)
    字符串反轉一個函數接受一個字符串作為參數,返回反轉後的字符串describe("String Reversal", () => { it("Should reverse string", () => { assert.equal(reverse("Hello World!
  • 8個簡單的JavaScript字符串方法
    英文 | https://medium.com/front-end-weekly/8-javascript-string-methods-as-simple-as-possible
  • JavaScript 中 Eval 函數的前世今生,執行代碼字符串
    Eval:執行代碼字符串內建函數 eval 允許執行一個代碼字符串。let result = eval(code);例如:let code = 'alert("Hello")';eval(code); // Hello代碼字符串可能會比較長
  • PHP中文字符串反轉編碼錯誤解決方式
    在使用PHP處理字符串反轉的時候,我們第一反應是使用PHP的內置函數strrev來處理,思維上是沒有問題的,但是我們需要知道一個問題,函數strrev是否可以處理中文漢字的字符串呢?帶著疑問我們一起來看一下。
  • LeetCode(7-整數反轉&&8-字符串轉換整數 (atoi)&&9-迴文數)
    整數反轉「題目描述」:給你一個 32 位的有符號整數 x ,返回 x 中每位上的數字反轉後的結果。如果反轉後整數超過 32 位的有符號整數的範圍 [−231,  231 − 1] ,就返回 0。假設環境不允許存儲 64 位整數(有符號或無符號)。
  • 在JavaScript中重複字符串的三種方法
    在本文中,我將解釋如何解決freeCodeCamp的「重複字符串重複字符串」挑戰。這涉及重複一個字符串一定次數。 我將介紹三種方法: 使用while循環 使用遞歸 使用ES6 repeat()方法 算法挑戰說明 重複給定的字符串(第一個參數)num次(第二個參數)。
  • TOP 48 算法和編程面試題,牛逼啊!
    編程面試題通常包含數據結構和基於算法的問題,以及一些邏輯問題,例如:如何在不使用臨時變量的情況下交換兩個整數?為了清晰,編程面試題需要劃分為不同主題。我們在面試中經常看到的領域是數組、鍊表、字符串、二叉樹以及有關算法的問題(例如字符串算法、快速排序或基數排序等排序算法),本文將介紹這些內容。
  • java開發工程師 javascript的字符串
    需要大量的練習、練習、練習來鞏固自己所獲得的知識。冰凍三尺非一日之寒,希望大家在學習java的日子裡一定一定要堅持不懈,嚴格要求。多練,多問,多百度。祝大家早日成為一名優秀的軟體工程師! 字符串是不管在java前端還是後臺中都是用的最多最多的一個數據類型,所有前後臺交互的數據都是字符串String類型。
  • python的內置函數eval:字符串運算
    前言最先認識eval,是在javascript中,eval() 函數可計算某個字符串,並執行其中的的 JavaScript 代碼。在javascript中,該方法只接受原始字符串作為參數,如果 string 參數不是原始字符串,那麼該方法將不作任何改變地返回。因此請不要為 eval() 函數傳遞 String 對象來作為參數。
  • JavaScript中的簡單排序算法
    英文 | https://medium.com/javascript-in-plain-english/simple-sorting-algorithms-in-javascript
  • AK leetcode 流浪計劃 - 數組反轉
    一、簡介二、基本操作步驟三、作用四、反轉模板交換元素的方法模板總結1 反轉數組區間2 反轉數組區間中的特定元素五、牛刀小試練習1 反轉字符串題目大意題目解析AC代碼練習2 反轉鍊表題目大意題目解析思路AC代碼練習3 反轉字符串中的元音字母題目大意題目解析AC代碼練習4 反轉字符串中的單詞 III題目大意題目解析AC代碼六、代碼模板七、總結八
  • JavaScript 基礎:「47」JavaScript 語言中 parseInt 函數用法詳解
    通過學習 JavaScript 算法及數據結構這一系列文章,你將會逐步掌握 JavaScript 基礎相關的知識。JavaScript 語言中 parseInt 函數用法詳解。我們在日常編程過程中,經常會遇到不同數據類型轉換的問題。用得比較多的是字符串轉換為整型,還有一些常用的不同進位轉換。
  • 編程老師告訴你,這5本JavaScript書籍你一定要讀!
    /5-javascript-books-you-should-read-a-coding-teachers-perspective-ecb15dfec832今天,我們將和大家推薦5本JavaScript書籍,這些書籍是由一個有著多年編程經驗的編程老師推薦的,以下是他的博客原文:作為一名老師,我在課程開發過程中需要閱讀很多東西,通常我會每周快速閱讀2-4本書,經常閱讀10-
  • 10 個 Python 字符串處理技巧
    那麼可以通過這個字符串處理入門教程,來了解一下利用Python處理字符串的一些基本操作。當前,自然語言處理和文本分析是研究和應用的熱點領域。這些領域包括各種具體的技能和概念,在深入具體實踐之前需要對它們有徹底的理解,為此,必須掌握一些基本的字符串操作和處理技巧。在我看來,必須掌握兩種字符串處理技巧:首先是正則表達式,一種基於模式的文本匹配方法。
  • JavaScript 函數replace揭秘
    在JavaScript中replace函數作為字符串替換函數,它是一個具有強大威力的字符串操作函數,對於常見字符串操作的推薦用法。在這篇文章中,博主想說的是第一個參數為正則的重載方式。對於正則表達式來說首先需要判斷是否是全局的(全局//g),它決定了不同的替換行為。如果是全局的則全部替換,非全局的則只替換第一個匹配的字符串。
  • java基礎編程題之String字符串練習
    以下是剛開始學習java的基礎編程題,每天持續更新java每個知識點的題目,持續練習,不斷提高java基本功,培養編程能力。