zoukankan      html  css  js  c++  java
  • 牛客网字符串排序编程题

    一、题目描述

    编写一个程序,将输入字符串中的字符按如下规则排序(一个测试用例可能包含多组数据,请注意处理)。

    规则 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).

    示例1

    输入

    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()方法,但方法也有局限性,不要把思想也局限了。

  • 相关阅读:
    Ubuntu Server 17.04安装GNOME指令
    docker应用笔记
    无线网络连接配置
    bind9的一些配置
    关于linux下的文件权限
    命令行模式下设置时区
    Linux下SSL证书申请以及配置到Nginx
    编译安装Nginx到Linux
    网页画流程图
    为什么Java字符串是不可变对象?
  • 原文地址:https://www.cnblogs.com/detanx/p/niuCodeTest1.html
Copyright © 2011-2022 走看看