字符串排序
来源:互联网 发布:数据录入兼职平台 编辑:程序博客网 时间:2024/06/01 22:27
问题描述
编写一个程序,将输入字符串中的字符按如下规则排序。规则 1 :英文字母从 A 到 Z 排列,不区分大小写。 如,输入: Type 输出: epTy规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。 如,输入: BabA 输出: aABb规则 3 :非英文字母的其它字符保持原来的位置。 如,输入: By?e 输出: Be?y示例1输入A Famous Saying: Much Ado About Nothing (2012/8).输出A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
思路
其实就是排除非字母的排序问题,且注意不区分大小,注意如果你采用排序算法来做这道题,一定要注意你选择的算法必须是稳定的,即保留元素的相对位置不变。
代码
代码一
package com.special.spet;import java.util.Scanner;/** * 字符串排序* 1.常规方法:将原字符串中的非字母与字母分开* 非字母数组中记录在原字符串中出现的索引* 字母数组用插入排序(必须是稳定的排序算法)* 然后对排序后的数组根据非字母数组的索引位置依次插入非字母* 复杂度O(n的平方)* 2.对以上方法进行改进:我们无需记录非字母* 对字母排序后,我们只要遍历原字符串,在是字母的情况下* 依次从字母数组取出来字符并代替!* @author special* @date 2017年9月18日 上午8:12:01*/public class Pro25 { /** * 字母比较大小,基于小写字母的比较 * @param ch1 * @param ch2 * @return */ public static boolean less(char ch1, char ch2){ ch1 = toLower(ch1); ch2 = toLower(ch2); if(ch1 < ch2) return true; else return false; } /** * 插入排序 * @param ch * @param length */ public static void sort(char[] ch , int length){ for(int i = 1; i < length; i++){ char temp = ch[i]; int j = i - 1; for(; j >= 0; j--){ if(less(temp, ch[j])) ch[j + 1] = ch[j]; else break; } /** * 不管以何种条件结束循环 * 都是赋值到j + 1的位置上 */ ch[j + 1] = temp; } } /** * 判断是不是字母 * @param ch * @return */ public static boolean isNotLetter(char ch){ if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) return false; return true; } /** * 转换成小写字母 * @param ch * @return */ public static char toLower(char ch){ if(ch >= 'A' && ch <= 'Z') return (char) ('a' + ch - 'A'); return ch; } /** * 字符串排序 * @param str * @return */ public static String sort(String str){ int length = str.length(); int[] flag = new int[length]; char[] sortedSeq = new char[length]; int flagSize = 0; int sortedSeqSize = 0; for(int i = 0; i < length; i++){ char temp = str.charAt(i); if(isNotLetter(temp)) flag[flagSize++] = i; else sortedSeq[sortedSeqSize++] = temp; } sort(sortedSeq,sortedSeqSize); for(int i = 0; i < flagSize; i++){ int index = flag[i]; for(int j = sortedSeqSize - 1; j >= index; j--){ sortedSeq[j + 1] = sortedSeq[j]; } sortedSeq[index] = str.charAt(index); sortedSeqSize++; } return new String(sortedSeq); } /** * 改进以上的sort方法 * 此方法不需要记录非字母数组 * 且不需要进行非字母的插入操作! * @param str * @return */ public static String improveSort(String str){ int length = str.length(); char[] sortedSeq = new char[length]; int sortedSeqSize = 0; for(int i = 0; i < length; i++){ char temp = str.charAt(i); if(!isNotLetter(temp)) sortedSeq[sortedSeqSize++] = temp; } sort(sortedSeq,sortedSeqSize); StringBuilder sortedString = new StringBuilder(str); int index = 0; /** * 我们这里不需要像上诉sort方法那样记录非字母,然后一个一个插进来 * 直接可以判断原字符串是不是字母,是的话,就依次从字母数组提取 * 不是的话,跳过,还是原字符 * 聪明的做法,赞一个! */ for(int i = 0; i < length; i++){ char temp = str.charAt(i); if(!isNotLetter(temp)) sortedString.setCharAt(i, sortedSeq[index++]); } return sortedString.toString(); } public static void main(String[] args){ Scanner input = new Scanner(System.in); while(input.hasNext()){ String str = input.nextLine(); String result = improveSort(str); System.out.println(result); } }}
代码二
package com.special.spet;import java.util.ArrayList;import java.util.List;import java.util.Scanner;/** ** @author special* @date 2017年9月18日 上午11:30:33*/public class Pro25Improve1 { /** * 没有采用排序,而是按字母表的每一位来考察原字符串是否含有。 * 有的话,就添加到list中,这样就不用考虑处理顺序,必然自动维护一个顺序 * 然后就在遍历一次字符串,其中的每一位字母位都从list中取 * 大神的杰作! * @param str * @return */ public static String sort(String str){ int length = str.length(); List<Character> letterList = new ArrayList<Character>(); for(int i = 0; i < 26; i++){ for(int j = 0; j < length; j++){ char temp = str.charAt(j); /** * 这里判断是否是按顺序来的字母的方法也很巧妙 * 以后可以借鉴一下 */ if((temp - 'a' == i) || (temp - 'A' == i)) letterList.add(temp); } } StringBuilder sortedString = new StringBuilder(str); int index = 0; for(int i = 0; i < length; i++){ char temp = str.charAt(i); if((temp >= 'a' && temp <= 'z') || (temp >= 'A' && temp <= 'Z')) sortedString.setCharAt(i, letterList.get(index++)); } return sortedString.toString(); } public static void main(String[] args) { Scanner input = new Scanner(System.in); while(input.hasNext()){ String str = input.nextLine(); String result = sort(str); System.out.println(result); } }}
代码三
package com.special.spet;import java.util.Scanner;/** ** @author special* @date 2017年9月18日 下午1:49:32*/public class Pro25Improve2 { public static boolean isNotLetter(char ch){ if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) return false; return true; } public static char toLower(char ch){ if(ch >= 'A' && ch <= 'Z') return (char) ('a' + ch - 'A'); return ch; } /** * 变形的冒泡法,类比希尔排序 * 非字母不参与排序 * @param str * @return */ public static char[] sort(String str){ int length = str.length(); char[] strArray = str.toCharArray(); int letterFirstIndex = 0; /** * 找到第一字母的位置 * 方便我们下面循环的时候,内循环少一点。 */ while(isNotLetter(strArray[letterFirstIndex])) letterFirstIndex++; for(int i = 0; i < length; i++){ int swapIndex = letterFirstIndex; for(int j = swapIndex + 1; j < length - i; j++){ if(isNotLetter(strArray[j])) continue; //如果该位置不是字母,继续下一个 /** * 若上一个位置的字母大于当前位置字母,则交换 */ if(toLower(strArray[swapIndex]) > toLower(strArray[j])){ char temp = strArray[j]; strArray[j] = strArray[swapIndex]; strArray[swapIndex] = temp; } /** * 无论是否交换,都应该记住j的位置 * 因为j的位置永远代表最大的 */ swapIndex = j; } } return strArray; } public static void main(String[] args) { Scanner input = new Scanner(System.in); while(input.hasNext()){ String str = input.nextLine(); char[] result = sort(str); System.out.println(result); } }}
代码四
package com.special.improve;import java.util.LinkedList;import java.util.Queue;import java.util.Scanner;/** * 类似桶排序* @author special* @date 2017年9月18日 下午2:29:39*/public class Pro25Improve3 { public static boolean isNotLetter(char ch){ if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) return false; return true; } public static char toLower(char ch){ if(ch >= 'A' && ch <= 'Z') return (char) ('a' + ch - 'A'); return ch; } /** * 变形的冒泡法,类比希尔排序 * 非字母不参与排序 * @param str * @return */ @SuppressWarnings("unchecked") public static char[] sort(String str){ int length = str.length(); char[] strArray = str.toCharArray(); /** * 这里Java创建泛型类数组,会报错 * 只能采用这种不安全的做法 */ Queue[] letterList = new LinkedList[26]; for(int i = 0; i < 26; i++) letterList[i] = new LinkedList(); for(int i = 0; i < length; i++){ if(isNotLetter(strArray[i])) continue; else letterList[toLower(strArray[i]) - 'a'].add(strArray[i]); } int noEmptyIndex = 0; for(int i = 0; i < length; i++){ if(isNotLetter(strArray[i])) continue; while(letterList[noEmptyIndex].size() == 0){ noEmptyIndex++; } strArray[i] = (char) letterList[noEmptyIndex].poll(); } return strArray; } public static void main(String[] args) { Scanner input = new Scanner(System.in); while(input.hasNext()){ String str = input.nextLine(); char[] result = sort(str); System.out.println(result); } }}
总结
多思考,多想,总有收获!
阅读全文
1 0
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序。
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 字符串排序
- 排序字符串
- 这些人都在使用超级表格
- ListView 侧滑删除
- vue的单向数据流和双向绑定解释
- BZOJ 3123 LCA + 主席树 + 启发式合并
- 【SoapUI】2、SoapUI进行API Mock测试分析
- 字符串排序
- 变量本质分析
- linux 下文件的创建时间、访问时间、修改时间和改变时间
- GLSL 转UnityShader
- mongoDB的入门
- xss攻击方法简单介绍了解
- Android4.4以上Uri转换成绝对路径的工具类
- Ubuntu安装Tomcta
- Java并发编程(二)--java线程安全的一些基础