成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊字符串轉樹結構

開發 前端
要對字符串進行處理,好像沒有什么比較好的方法,理不出頭緒。當我們遇到這種直接從數據結構出發想不出辦法的問題時,這時可能就要換個思路了,能否將它轉換為另一種數據結構呢?

前言

有一個多行字符串,每行開頭會用空格來表示它的層級關系,每間隔一層它的空格總數為2,如何將它轉為json格式的樹型數據?本文就跟大家分享下這個算法,歡迎各位感興趣的開發者閱讀本文。

例如有一個字符串:

const text = `
Language
JavaScript
TypeScript
NodeJS
HTML
Server
DataBase
MongoDB
System
Linux
Window
`;

將其轉換為有層次結構的json數據后為:

{
"name":"root",
"children":[
{
"name":"Language",
"children":[
{
"name":"JavaScript",
"children":[
{
"name":"TypeScript"
},
{
"name":"NodeJS"
}
]
},
{
"name":"HTML"
}
]
},
{
"name":"Server",
"children":[
{
"name":"DataBase",
"children":[
{
"name":"MongoDB"
}
]
}
]
},
{
"name":"System",
"children":[
{
"name":"Linux"
},
{
"name":"Window"
}
]
}
]
}

思路分析

乍一看,要對字符串進行處理,好像沒有什么比較好的方法,理不出頭緒。當我們遇到這種直接從數據結構出發想不出辦法的問題時,這時可能就要換個思路了,能否將它轉換為另一種數據結構呢?

審題后發現,我們需要的數據元素在字符串中總是獨占一行的,那么我們就要對每一行進行處理,此時最好的方式就是將它切割成數組。

那么,我們就以換行符作為切割點來構造數組,如下所示:

[
"","Language"," JavaScript", " TypeScript"," NodeJS", " HTML","Server"," DataBase"," MongoDB","System"," Linux"," Window",""
]

觀察數組中的每個元素后,我們發現最頂層的數據開頭無空格,每間隔一層,開頭就會多兩個空格。按照從前往后的順序依次讀取數據,將后一個數據與其之前的數據進行比較,進而確定他們之間的層次關系。

分析到這里,相信很多開發者已經看出了這個比較方式滿足了“后入先出”原則,因此,我們可以用棧來解決這個問題,如下所示:

  • 準備2個棧,一個用于存放每層的字符串,另一個用于存放每層的空格數。
  • 默認將root入棧,將它的空格數定為-1。

圖片

接下來,我們將每個元素逐一入棧,分析下它的過程。如下圖所示,我們列舉了部分元素的入棧比對過程,通過觀察后,總結出了如下幾條規律。

  • 獲取入棧元素的空格總數
  • 獲取棧頂(deepStack)元素,判斷入棧元素的空格總數是否大于棧頂元素。

滿足條件則獲取strStack的棧頂元素,將入棧元素元素放入它的子級

否則,將兩個棧的元素依次出棧。直至入棧元素的空格總數比deepStack的棧頂元素大,獲取strStack的棧頂元素,將入棧元素元素放入它的子級

  • 將入棧元素以及它的空格總數分別放入對應的棧中
  • 直至所有元素都入棧比對完成,此問題得到解決

圖片

注意:為了讓讀者更直觀的看出規律,strStack棧中的元素用字符串直接代替了,實際上棧中存儲的數據是一個對象,該對象包含了name屬性和children屬性。當前入棧元素也會構造成一個對象,得出棧頂元素(deepStack)與入棧元素空格總數的比對結果后,會將入棧元素對象放進棧頂元素(strStack)的children中。

實現代碼

經過上面的分析,我們已經得出了完整的實現思路,接下來我們來看下代碼的實現。

/**
* 字符串轉樹結構
* @param text
* @constructor
*/
export function DataConversion(text: string): nodeObj {
const splitArr = text.split("\n");

const json = { name: "root" };
const strStack = new Stack();
const deepStack = new Stack();
strStack.push(json);
deepStack.push(-1);

for (let i = 0; i < splitArr.length; i++) {
let str = splitArr[i];
if (!str) continue;
// 獲取空格總數
const len = str.lastIndexOf(" ") + 1;
str = str.replace(/\s/g, "");
const curObj = { name: str };

// 尋找當前入棧元素的父層級
while (len <= deepStack.peek()) {
deepStack.pop();
strStack.pop();
}
const stackTop: nodeObj = strStack.peek();
stackTop.children
? stackTop.children.push(curObj)
: (stackTop.children = [curObj]);

// 元素入棧,繼續下一輪的比對
strStack.push(curObj);
deepStack.push(len);
}

return json;
}

注意:上述代碼中聲明了一個自定義類型nodeObj以及一個自定義類Stack,完整代碼請在示例代碼中查看。

最后,我們將開頭的例子代入上述代碼中,校驗下它能否正確解決問題。

const text = `
Language
JavaScript
TypeScript
NodeJS
HTML
Server
DataBase
MongoDB
System
Linux
Window
`;

const textJSON = DataConversion(text);
console.log(JSON.stringify(textJSON));

圖片

圖片

示例代碼

本文用到的代碼完整版請移步:

  • DataConversion.ts
  • DataConversion-test.ts
責任編輯:武曉燕 來源: 神奇的程序員
相關推薦

2009-06-23 14:13:00

Java字符串

2021-11-15 07:47:40

字符串位置存儲

2009-11-25 09:13:41

PHP數組轉字符串PHP字符串轉數組

2009-11-16 17:59:13

PHP數組轉字符串

2021-12-21 11:39:01

數據結構算法同構字符串

2012-02-06 15:22:16

Java

2021-12-24 11:59:47

數據結構算法字符串

2019-03-07 15:43:22

Redis數據SDS

2024-04-01 08:41:39

字符串.NET

2010-04-15 16:47:46

Oracle字段

2024-06-26 07:58:06

2014-01-02 16:14:10

PostgreSQL字符串

2009-07-16 17:01:09

Swing字符串

2023-01-11 16:49:13

MySQL數據庫

2011-08-10 18:47:18

Cocoa字符串

2010-11-26 09:51:54

MySQL字符串

2010-09-09 11:48:00

SQL函數字符串

2021-03-08 08:23:24

Java字符串截取

2010-06-28 15:18:51

SQL Server

2021-12-23 14:09:43

數據結構算法字符串
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一区二区久久 | 欧美国产日韩在线观看成人 | 国产蜜臀 | 一区二区高清不卡 | 波多野结衣一区二区三区 | 精品不卡 | 亚洲草草视频 | 国产精品久久久久久妇女6080 | 久久香蕉精品视频 | 99在线免费观看视频 | 精品伊人久久 | 国产精品二区三区在线观看 | 久久久久无码国产精品一区 | 国产成人综合亚洲欧美94在线 | 久久久久久综合 | 久久99精品视频 | 国产综合久久久 | 国产一区二区欧美 | 福利视频一区二区三区 | 国产清纯白嫩初高生视频在线观看 | 国产一区不卡 | 99re在线视频精品 | 全免费a级毛片免费看视频免费下 | 亚洲性人人天天夜夜摸 | 日韩国产在线观看 | 国内自拍视频在线观看 | 久久成 | 亚洲一区不卡在线 | 超级碰在线 | 国产91视频播放 | av天天干 | 欧美亚洲国语精品一区二区 | 欧美激情一区 | 国产无套一区二区三区久久 | 欧美日韩专区 | 久草电影网| 久久性色 | 一区二区三区免费在线观看 | 亚洲国产高清高潮精品美女 | 九色在线观看 | 久久精品无码一区二区三区 |