字符串低位优先排序真的只能排序字符串相同的字符么?

最近在刷剑指Offer上的题时遇到一题:

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

突然想到使用LSD算法,

 1 package com.roysatm.niuke;
 2
 3
 4 /**
 5  * Created by roysatm on 2016/5/30.
 6  */
 7 public class SolutionPrintMinNumber {
 8
 9     /**
10      * 采用LSD(低位优先排序)思想,可以说能把高位优先排序取代。
11      * 基本是O(n)时间复杂度完成,没有使用任何java集合框架
12      * 代码可能不是最优,特别是空间复杂度方面
13      */
14     public String PrintMinNumber(int[] numbers) {
15
16         if (numbers == null || numbers.length == 0) {
17             return "";
18         }
19
20         String[] str = new String[numbers.length];
21         int w = 0;
22         //将int数组转成string数组
23         for (int i = 0; i < numbers.length; i++) {
24             str[i] = numbers[i] + "";
25         }
26         //计算出str数组中长度最长的字符串长度
27         for (int i = 0; i < str.length; i++) {
28             if (str[i].length() > w) {
29                 w = str[i].length();
30             }
31         }
32
33         StringBuilder sb = new StringBuilder();
34
35         String[] array = PrintMinNumber(str, w);
36         //将String数组转换成String字符串
37         for (int i = 0; i < array.length; i++) {
38             sb.append(array[i]);
39         }
40         return sb.toString();
41     }
42
43     public String[] PrintMinNumber(String[] str, int w) {
44
45         /**
46          * 低位优先排序,主要看点是getCharAt(String s, int index)函数的变化
47          由于getCharAt(String s, int index)函数的改变,LSD可以排长度不同的字符串
48          * **/
49
50         int R = 256;
51         int N = str.length;
52         String[] aux = new String[N];
53
54         for (int i = w - 1; i >= 0; i--) {
55
56             int[] count = new int[R + 1];
57
58             for (int j = 0; j < N; j++) {
59                 count[getCharAt(str[j], i) + 1]++;
60             }
61
62             for (int j = 0; j < R; j++) {
63                 count[j + 1] += count[j];
64             }
65
66             for (int j = 0; j < N; j++) {
67                 aux[count[getCharAt(str[j], i)]++] = str[j];
68             }
69
70             for (int j = 0; j < N; j++) {
71                 str[j] = aux[j];
72             }
73         }
74
75         return str;
76     }
77
78     private char getCharAt(String s, int index) {
79
80         if (s.length() <= index) {
81             return s.charAt(s.length() - 1);
82         } else {
83             return s.charAt(index);
84         }
85     }
86
87     public static void main(String[] args) {
88         int[] a = {12, 2, 34, 13, 54};
89         SolutionPrintMinNumber spm = new SolutionPrintMinNumber();
90         String str = spm.PrintMinNumber(a);
91         System.out.print(str + " ");
92
93     }
94 }

以上算法是LSD排序算法升级版,不仅能排序字符串长度相同的数组,还能像高位优先一样排序字符串不同的数组。

下次有时间再详细写写.......

时间: 2024-10-09 17:21:43

字符串低位优先排序真的只能排序字符串相同的字符么?的相关文章

算法-低位优先的字符串排序

低位优先的字符串排序相当于是对键索引计数方法的一个扩展,主要用于处理固定长度字符串,比如说手机号,固定电话,银行卡卡号,字符串的长度为N,从右向左开始进行每个键作为值开始遍历,实现比较简单: -(void)lowSort:(NSMutableArray *)dataSource singleLength:(NSInteger)len { NSInteger sourceCount=[dataSource count]; NSInteger R=256; NSMutableArray *tempA

字符串排序(非字典排序)

2015.3.11 今天阿里面试,最后给我出了一个算法题,如下: 一个数组字符串,对其中的字符串进行排序,排序规则如下:长度越小越排在前面,长度相同则按照字符串大小排序.举个例子:“a”,"ab","Ab","b","abc",排序后 : a, b, Ab, ab, abc. 和室友讨论一下,由他想出了如下的方法:按照字符串的每一位进行排序,提前结束的字符串在相应位比较时总是最小.完成后,得到的结果也便是我们想要的了. 具体代

使用合并排序和快速排序对字符串按长度排序

前段时间要对字符串集合进行按长度排序,字符串长度长的排在队列前面,最短的排在最后,可以使用两种排序方法进行排序,其中快速排序的效能会好些,但快速排序在字符串的集合非常大的时候,有时会得不到正确的结果,具体原因还不清楚. 1.合拼排序的代码 using System; using System.Collections.Generic; using System.Text; namespace FtpproxyDownRule.DBUtility { public class sortbyStrin

编写一个字符串排序程序,对一个字符串的数值进行从小到大的排序,要求使用包装类对数值类型的字符串转换成整型进行排序

package cn.lyun.zzj; import java.util.Arrays; public class WrapperTest { private static final String SPACE_SEPARATOR = " "; //不可以放在一个类里面. public static void main(String[] args) { String numStr = "20 78 9 -7 88 36 29"; System.out.printl

从键盘输入一个字符串,按照字符顺序从小到大进行选择排序,并要求删除重复的字符

/* 从键盘输入一个字符串,按照字符顺序从小到大进行选择排序,并要求删除重复的字符 思路: 选择排序:比较找到最小的下标,和第i个交换位置. 删除重复字符:用k计算不相等的个数,替换. */ #include <stdio.h> #include<string.h> void insetsort(char *str,int n){ int i,j,min,temp,k; char sh[n]; for(i=0;i<n;i++){ min=i; for(j=i+1;j<n

ArrayList去除集合中字符串的重复值,只能在本集合内操作

/* * 需求:ArrayList去除集合中字符串的重复值,只能在本集合内操作 * * 分析: * 1.创建一个集合对象 * 2.添加多个字符串元素 * 3.用选择排序方法去比较 * A:如有相同的,则删除此元素 * B:没有,则保留 * 4.遍历输出 新集合 */ package com.ma.arraylist; import java.util.ArrayList; import java.util.Iterator; /** * ArrayList去除集合中字符串的重复值,只能在本集合内

【算法】计数排序、桶排序和基数排序详解

01.计数排序.桶排序与基数排序 并不是所有的排序 都是基于比较的,计数排序和基数排序就不是.基于比较排序的排序方法,其复杂度无法突破\(n\log{n}\) 的下限,但是 计数排序 桶排序 和基数排序是分布排序,他们是可以突破这个下限达到O(n)的的复杂度的. 1. 计数排序 概念 计数排序是一种稳定的线性时间排序算法.计数排序使用一个额外的数组C,使用 C[i] 来计算 i 出现的次数.然后根据数C来将原数组A中的元素排到正确的位置. 复杂度 计数排序的最坏时间复杂度.最好时间复杂度.平均时

基数排序与桶排序,计数排序【详解】

桶排序简单入门篇^-^ 在我们生活的这个世界中到处都是被排序过的东东.站队的时候会按照身高排序,考试的名次需要按照分数排序,网上购物的时候会按照价格排序,电子邮箱中的邮件按照时间排序……总之很多东东都需要排序,可以说排序是无处不在.现在我们举个具体的例子来介绍一下排序算法. 首先出场的是我们的主人公小哼,上面这个可爱的娃就是啦.期末考试完了老师要将同学们的分数按照从高到低排序.小哼的班上只有5个同学,这5个同学分别考了5分.3分.5分.2分和8分,哎,考得真是惨不忍睹(满分是10分).接下来将分

计数排序与位图排序

计数排序(Counting sort)是一种稳定的线性时间排序算法.计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数.然后根据数组C来将A中的元素排到正确的位置.计数排序不是比较排序,排序的速度快于任何比较排序算法.由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存.计数排序更适合于小范围集合的排序.比如100万学生参加高考,我们想对这100万学生的数学成绩(