方法:冒泡排序,对比每两个字符串的每一个字符。具体的可见代码中的注释。
思考路线:需要区分数字字符和非数字字符,故可知数字字符为此条件中的”特殊字符“,即特殊情况,需单独处理。数字字符的ASCII值为48-57。每次比较两个字符串(如字符串j和字符串j+1)中的每一个字符。
情况如下:
1、j中为数字,j+1不为数字。 此时需要交换两字符串位置
2、j中为数字,j+1为数字。
此时需要比较:
j>j+1时交换,
j<j+1时跳出,
j==j+1时需要比较j的字符串长度是否大于j+1的字符串长度,当大于时交换,反之跳出
3、j中不为数字,j+1为数字。此时不需要交换,直接跳出比较即可
4、j中不为数字,j+1不为数字。
代码修正日志
2015-09-23 优化代码编写,修正类似“1717A”被错误排在“1717”之前的错误,增添若字符串为空,则将其排在最前面。
2015-09-24 添加”思考路线“
代码
无奈了, 排版几次都没弄好,缩进不知为何都消失了,来http://blog.csdn.net/u011091122/article/details/48677933看有缩进版的吧。
var arry=["STEWARTS RT BEER 6/4/12 NR","7-UP 4/6/8 CN","",
"1217-UP TEN 2/12 CN","DIET 7-UP 4/6/8 CN",
"1a1","FIJI 2/4/16.9 PET","",
"1717A","1717","1717B","1716",
"1716A","ABC","ABD","ACD","A123","A12D3","BCD","A123D",
"FIJI 6/6/300 ML","FIJI 24/16.9 PET",
"7-UP TEN 2/12 CN","217-UP TEN 2/12 CN"];
var blnCheck = false;
var i = arry.length,j;
while(i>0){
for(j=0;j<i-1;j++){
tmpLen = Math.min(arry[j].length,arry[j+1].length);
//当j+1为空时,交换(即将其排在最前),反之正常排序
if(tmpLen===0&&arry[j+1].length === 0){
blnCheck = true;
}else{
for(k=0;k<tmpLen;k++){
//若arry[j][K]不为数字,j+1为数字 直接跳出,不需要交换
if((arry[j][k].charCodeAt()<48||arry[j][k].charCodeAt()>57)
&&(48<=arry[j+1][k].charCodeAt()&&arry[j+1][k].charCodeAt()<=57)){
break;
}
//若arry[j][K]为数字,j+1不为数字 交换顺序
/*若arry[j][K]为数字,j+1为数字
*或arry[j][K]不为数字,i+1不为数字
* j>j+1 交换并跳出 j<j+1不交换并跳出
*/
if((48<=arry[j][k].charCodeAt()&&arry[j][k].charCodeAt()<=57)
&&(arry[j+1][k].charCodeAt()<47||arry[j+1][k].charCodeAt()>57)){
blnCheck = true;
break;
}else if(
((48<=arry[j][k].charCodeAt()&&arry[j][k].charCodeAt()<=57)
&&(48<=arry[j+1][k].charCodeAt()&&arry[j+1][k].charCodeAt()<=57))
||((arry[j][k].charCodeAt()<48||arry[j][k].charCodeAt()>57)
&&(arry[j+1][k].charCodeAt()<48||arry[j+1][k].charCodeAt()>57))){
if(arry[j][k]<arry[j+1][k]){
break;
}
if(arry[j][k]>arry[j+1][k]){
blnCheck = true;
break;
}else if((k==tmpLen-1&&arry[j][k]==arry[j+1][k])&&(arry[j].length>tmpLen)){
blnCheck = true;
break;
}
}
}
}
if (blnCheck) {
tempExchangVal = arry[j];
arry[j] = arry[j + 1];
arry[j + 1] = tempExchangVal;
}
blnCheck = false;
}
i--;
}
arry.forEach(function(e){
document.write("</br>"+e+"</br>");
});
效果
DIET 7-UP 4/6/8 CN FIJI 2/4/16.9 PET FIJI 24/16.9 PET FIJI 6/6/300 ML STEWARTS RT BEER 6/4/12 NR 1a1 1217-UP TEN 2/12 CN 217-UP TEN 2/12 CN 7-UP TEN 2/12 CN 7-UP 4/6/8 CN
没想到第一次在CSDN上问问题就开阔了些眼界,主要分析见下文。
代码
var arry=["STEWARTS RT BEER 6/4/12 NR",
"7-UP 4/6/8 CN",
"1217-UP TEN 2/12 CN",
"DIET 7-UP 4/6/8 CN",
"1a1",
"FIJI 2/4/16.9 PET",
"FIJI 6/6/300 ML",
"FIJI 24/16.9 PET",
"7-UP TEN 2/12 CN",
"217-UP TEN 2/12 CN"];
arry = arry.sort(function(a, b){
if(a< b) return -1;
if(a> b) return 1;
return 0;
});
for ( var i = 0; i < arry.length; i++ ) {
var e = arry[0];
if ( !isNaN(e.charAt(0)) ) {
arry.splice(0,1);
arry = arry.concat([e]);
}
}
console.log(arry);
效果
DIET 7-UP 4/6/8 CN FIJI 2/4/16.9 PET FIJI 24/16.9 PET FIJI 6/6/300 ML STEWARTS RT BEER 6/4/12 NR 1217-UP TEN 2/12 CN 1a1 217-UP TEN 2/12 CN 7-UP 4/6/8 CN 7-UP TEN 2/12 CN
单独把这个列出来,是由于里面的一个for循环写的很特别,让我这个小白开阔了眼界。
for ( var i = 0; i < arry.length; i++ ) {
var e = arry[0];
if ( !isNaN(e.charAt(0)) ) {
arry.splice(0,1);
arry = arry.concat([e]);
}
}
isNaN(x) 函数用于检查其参数是否是非数字值。如果 x 是特殊的非数字值 NaN(或者能被转换为这样的值),返回的值就是 true。如果 x 是其他值,则返回 false。
isNaN() 函数可用于判断其参数是否是 NaN,该值表示一个非法的数字(比如被 0 除后得到的结果)。
如果把 NaN 与任何值(包括其自身)相比得到的结果均是 false,所以要判断某个值是否是 NaN,不能使用 == 或 === 运算符。正因为如此,isNaN() 函数是必需的。
stringObject.charAt(index)方法可返回指定位置的字符。请注意,JavaScript 并没有一种有别于字符串类型的字符数据类型,所以返回的字符是长度为 1 的字符串。
arrayObject.splice(index,howmany,item1,.....,itemX)方法向/从数组中添加/删除项目,然后返回被删除的项目。注释:该方法会改变原始数组。
该循环是在已经进行过一次排序将首字符为数字的放在前面不是数字的放在后面(既遵循ASCII表的升序)前提下进行的
1、变量e保存每次循环时字符串数组arry的首字符串arry[0]
2、当isNaN()找到的是数字的时,使用splice()函数删除该字符串,由于splice会改变原始数组,故原arry[1]会变为新arry[0]
3、通过concat()连接函数,将之前用e存储的arry[0]添加到新arry之后。
通过循环此3步到最后即可完成排序工作。