一、題目描述
編寫一個程式,將輸入字串中的字元按如下規則排序(一個測試用例可能包含多組資料,請注意處理)。
規則 1 :英文字母從 A 到 Z 排列,不區分大小寫。
如,輸入: Type 輸出: epTy
規則 2 :同一個英文字母的大小寫同時存在時,按照輸入順序排列。
如,輸入: BabA 輸出: aABb
規則 3 :非英文字母的其它字元保持原來的位置。
如,輸入: By?e 輸出: Be?y
樣例:
輸入:
A Famous Saying: Much Ado About Nothing(2012/8).
輸出:
A aaAAbc dFgghh : iimM nNn oooos Sttuuuy (2012/8).
輸入
A Famous Saying: Much Ado About Nothing (2012/8).
#$Y^!#Pf&~#FUyTtAfZhCs&Dly%M@(muOI@Le^mydvc((w$x-cP&t-f$R%CCp)bCck@P-ag
輸出
A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
#$A^!#ab&~#CccCCCcDdef&Fff%g@(hIkl@LM^mmOPP((p$P-Rs&T-t$t%Uuv)wxYy@y-yZ
二、解題思路
1、思路一:字串分割
對字串分割,記錄非字母位置和單詞長度,再對字母排序,排序後按照單詞長度分割,並非字母位置插入相應字元
最後發現不可行,原因,操作過於繁瑣且空間消耗過高,輸入不為單詞字串時,問題較多,輸入存在用例如下:#$Y^!#Pf&~#FUyTtAfZhCs&Dly%M@(muOI@Le^mydvc((w$x-cP&t-f$R%CCp)bCck@P-ag
2、思路二:字母替換
將字串中所有的大小寫字元存入一個陣列中,將陣列排序,然後遍歷字串,當為字母時從陣列中獲取,並下標後移一位
難點:所有的字母並不是按照常規排序,而是需要保留原來字串中的順序,且從A-Z排序
嘗試一、使用陣列的sort()方法,排序結果無法保留原始相同字母的相對位置,且大寫字母在前,小寫在後
原始:["Y","y","y","y","P","P","p","P","f","F","f","f","U","u","T","t","t","A","a","Z","h","C","c","c","C","C","C","c","s","D","d","l","L","M","m","m","O","I","e","v","w","x","R","b","k","g"] 結果:["A", "C", "C", "C", "C", "D", "F", "I", "L", "M", "O", "P", "P", "P", "R", "T", "U", "Y", "Z", "a", "b", "c", "c", "c", "d", "e",
"f", "f", "f", "g", "h", "k", "l", "m", "m", "p", "s", "t", "t", "u", "v", "w", "x", "y", "y", "y"]
嘗試二、在存入字母時對相同字母保持相對位置不變存入陣列,再使用arr.sort(function(a,b){return a.toLocaleLowerCase()>=b.toLocaleLowerCase()?1:-1;});排序,排序結果部分保留相對位置,任然有些字母的相對位置發生了變化
let upper = str[i].toLocaleUpperCase(); let lower = str[i].toLocaleLowerCase(); if(strArray.indexOf(upper) !== -1 || strArray.indexOf(lower) !== -1) { let subscript1 = strArray.lastIndexOf(upper); let subscript2 = strArray.lastIndexOf(lower); let subscript = Math.max(subscript1,subscript2) strArray.splice(subscript+1,0,str[i]) }else { strArray.push(str[i]) }
原始:["Y","y","y","y","P","P","p","P","f","F","f","f","U","u","T","t","t","A","a","Z","h","C","c","c","C","C","C","c","s","D","d","l","L","M","m","m","O","I","e","v","w","x","R","b","k","g"] 結果:["a", "A", "b", "c", "c", "C", "C", "c", "C", "C", "d", "D", "e", "f", "F", "f", "f", "g", "h", "I", "k", "l", "L", "M", "m", "m", "O", "P", "P", "P", "p", "R", "s", "t", "T", "t", "U", "u", "v", "w", "x", "Y", "y", "y", "y", "Z"]
嘗試三、在存入時使用二維陣列,每個子陣列的第二個值存放0,1標識當前字母的大小寫,存入時全部存小寫,然後使用sort()方法排序,結果sort()方法排序會先取陣列的第一個值排序,再取第二個值排序,所以排序後即使在將大寫轉換回來,但相對字母的順序發生了變化,相同字母在一起,但大寫在前小寫在後
原始:["Y","y","y","y","P","P","p","P","f","F","f","f","U","u","T","t","t","A","a","Z","h","C","c","c","C","C","C","c","s","D","d","l","L","M","m","m","O","I","e","v","w","x","R","b","k","g"]
結果:A,a,b,C,C,C,C,c,c,c,D,d,e,F,f,f,f,g,h,I,k,L,l,M,m,m,O,P,P,P,p,R,s,T,t,t,U,u,v,w,x,Y,y,y,y,Z
思考:自己陷入了誤區,字母陣列的序列必須用sort()方法來實現
嘗試四、建立26個大寫字母的陣列,使用for迴圈去迴圈遍歷所存的字串的字母的陣列,依次從A-Z去判斷,存在就放入一個新的陣列,這樣陣列從A-Z進行了排序,字母的相對位置也沒有發生變化
var character = new Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"); for(let s=0;s < character.length;s ++) { for(let k = 0;k < strArray.length; k ++) { if(character[s] === strArray[k] || character[s].toLocaleLowerCase() === strArray[k]) { resultArray.push(strArray[k]) } } }
原始:Y,P,f,F,U,y,T,t,A,f,Z,h,C,s,D,l,y,M,m,u,O,I,L,e,m,y,d,v,c,w,x,c,P,t,f,R,C,C,p,b,C,c,k,P,a,g 結果:A,a,b,C,c,c,C,C,C,c,D,d,e,f,F,f,f,g,h,I,k,l,L,M,m,m,O,P,P,p,P,R,s,T,t,t,U,u,v,w,x,Y,y,y,y,Z
三、完整程式碼
let resultArr = [] while(lines = readline()) { resultArr.push(changeString(lines)) } console.log(resultArr.join(" ")) function changeString(str) { var strArray = [],resultArray = [] for(let i = 0;i < str.length;i ++) { if(/[A-Za-z]/.test(str[i])) { strArray.push(str[i]) } } var character = new Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"); for(let s=0;s < character.length;s ++) { for(let k = 0;k < strArray.length; k ++) { if(character[s] === strArray[k] || character[s].toLocaleLowerCase() === strArray[k]) { resultArray.push(strArray[k]) } } } let index = 0,newstr = ""; for(let j = 0;j < str.length;j ++) { if(/[A-Za-z]/.test(str[j])) { newstr += resultArray[index]; index ++ }else { newstr += str[j] } } return newstr }
四、總結
1、在看問題時要發現問題的關鍵點,例如本題中的關鍵點:字母排序,大小寫相對位置不變,非字母位置不變;
2、多嘗試、發現總結問題,這個方法不行是為什麼?哪兒出錯了?針對問題尋找其他方法;
3、不要陷入知識誤區,例如本題中的排序,一想到排序就想到使用sort()方法,但方法也有侷限性,不要把思想也侷限了。