按数字顺序对N个数字进行排序
给定一个N个数字范围,例如[1到100],按数字顺序对数字进行排序(即)对于数字1到100,排序后的输出将是 1 10 100 11 12 13 。 。 。 19 2 20 21..... 99
这就像基数排序一样,只是数字按照与正常基数排序相反的顺序排序。
我尝试将每个数字中的所有数字存储为链表以加快操作速度,但这会导致很大的空间复杂度。
我需要一个解决这个问题的可行算法。
从所有答案来看,“转换为字符串”是一个选项,但是没有其他方法可以做到这一点吗? 还可以给出如上所述的用于对字符串进行排序的算法。
Given a N number range E.g. [1 to 100], sort the numbers in digit order (i.e) For the numbers 1 to 100, the sorted output wound be
1 10 100 11 12 13 . . . 19 2 20 21..... 99
This is just like Radix Sort but just that the digits are sorted in reversed order to what would be done in a normal Radix Sort.
I tried to store all the digits in each number as a linked list for faster operation but it results in a large Space Complexity.
I need a working algorithm for the question.
From all the answers, "Converting to Strings" is an option, but is there no other way this can be done?
Also an algorithm for Sorting Strings as mentioned above can also be given.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
使用您喜欢的任何排序算法,但将数字作为字符串进行比较,而不是作为数字进行比较。这基本上是常规数字的字典排序。以下是 C 语言中的 gnome 排序示例:
当然,这需要在
stdlib.h
中存在非标准itoa
函数。更标准的替代方案是使用 sprintf,但这会使代码更加混乱。您最好先将整个数组转换为字符串,然后排序,然后再将其转换回来。编辑:作为参考,这里的相关位是
strcmp(itoa(*iter, &buf1, 10), itoa(*(iter-1), &buf2, 10) > ;= 0
,它取代了*iter >= *(iter-1)
。Use any sorting algorithm you like, but compare the numbers as strings, not as numbers. This is basically lexiographic sorting of regular numbers. Here's an example gnome sort in C:
Of course, this requires the non-standard
itoa
function to be present instdlib.h
. A more standard alternative would be to usesprintf
, but that makes the code a little more cluttered. You'd possibly be better off converting the whole array to strings first, then sort, then convert it back.Edit: For reference, the relevant bit here is
strcmp(itoa(*iter, &buf1, 10), itoa(*(iter-1), &buf2, 10) >= 0
, which replaces*iter >= *(iter-1)
.我有一个解决方案,但不完全是一个算法。您所需要做的就是将所有数字转换为字符串并转换为字符串。将它们排序为字符串..
I have a solution but not exactly an algorithm.. All you need to do is converts all the numbers to strings & sort them as strings..
下面是如何使用递归函数来实现它(代码是 Java 中的):
您可以这样调用它:
编辑:
我用 C++ 翻译了我的代码 这里:
基本上,这个想法是:对于每个数字(0-9),如果它在
minimum
和maximum< 之间,我将其添加到数组中/代码>。然后,我使用该数字作为前缀调用相同的函数。它执行相同的操作:对于每个数字,它将其添加到前缀 (
prefix * 10 + i
),如果它在限制之间,则将其添加到数组中。当newNumber
大于最大值时,它会停止。Here is how you can do it with a recursive function (the code is in Java):
You call it like this:
EDIT:
I translated my code in C++ here:
Basically, the idea is: for each digit (0-9), I add it to the array if it is between
minimum
andmaximum
. Then, I call the same function with this digit as prefix. It does the same: for each digit, it adds it to the prefix (prefix * 10 + i
) and if it is between the limits, it adds it to the array. It stops whennewNumber
is greater than maximum.我认为如果你将数字转换为字符串,你可以使用字符串比较来对它们进行排序。
您可以使用 anny 排序算法。
“1”< “10”< “100”< “11”...
i think if you convert numbers to string, you can use string comparison to sort them.
you can use anny sorting alghorighm for it.
"1" < "10" < "100" < "11" ...
优化存储数字的方式:使用二进制编码的十进制 (BCD)< /a> 可以简单地访问特定数字的类型。 然后您可以使用当前的算法,Steve Jessop 正确地将其识别为 最高有效数字基数排序。
将每个数字存储在链接列表中会以两种不同的方式浪费空间:
char
或short
类型占用 8 位,int
最多可占用 64 位。这比最佳解决方案使用的内存多 2 倍到 16 倍!内存效率更高的解决方案在内存中连续存储 BCD 位数字:
如果加法/乘法等其他操作不重要,一种选择是分配足够的内存来存储每个 BCD 数字加上一个 BCD 终止符。 BCD 终止符可以是不用于表示 BCD 数字的 4 位的任意组合(如二进制
1111
)。不过,以这种方式存储将使其他操作(例如加法和乘法)变得更加棘手。请注意,这与转换为字符串并按字典顺序对这些字符串进行排序的想法非常相似。整数在计算机内部以二进制(基数 2)形式存储。以 BCD 存储更像是基数 10(实际上是基数 16,但忽略了 6 个组合),而字符串就像基数 256。字符串将使用大约两倍的内存,但已经编写了高效的函数来对字符串进行排序。 BCD 可能需要开发自定义 BCD 类型来满足您的需求。
Optimize the way you are storing the numbers: use a binary-coded decimal (BCD) type that gives simple access to a specific digit. Then you can use your current algorithm, which Steve Jessop correctly identified as most significant digit radix sort.
Storing each digit in a linked list wastes space in two different ways:
char
orshort
type takes 8 bits, and anint
can take up to 64 bits. That's using 2X to 16X more memory than the optimal solution!A more memory-efficient solution stores BCD digits contiguously in memory:
One option, if other operations like addition/multiplication are not important, is to allocate enough memory to store each BCD digit plus one BCD terminator. The BCD terminator can be any combination of 4 bits that is not used to represent a BCD digit (like binary
1111
). Storing this way will make other operations like addition and multiplication trickier, though.Note this is very similar to the idea of converting to strings and lexicographically sorting those strings. Integers are internally stored as binary (base 2) in the computer. Storing in BCD is more like base 10 (base 16, actually, but 6 combinations are ignored), and strings are like base 256. Strings will use about twice as much memory, but there are already efficient functions written to sort strings. BCD's will probably require developing a custom BCD type for your needs.
编辑:我错过了它是一个连续的范围。既然如此,所有谈论对数组进行排序的答案都是错误的(包括你在问题中所说的它就像基数排序的想法),而True Soft的答案是正确的。
就像基数排序,但只是数字以相反的顺序排序
很好看:-) 如果你真的这样做,有趣的是,它被称为 MSD 基数排序。
http://en.wikipedia.org/wiki/Radix_sort#Most_significant_digit_radix_sorts
您可以实施一个非常简单,或者带有很多高科技和大张旗鼓的。在大多数编程语言中,您的特定示例面临着轻微的困难。从整数的自然存储格式中提取十进制数字并不是一个特别快的操作。您可以忽略这一点并查看它最终需要多长时间(推荐),或者您可以通过在排序之前将所有数字转换为十进制字符串来添加更多的宣传。
当然,您不必将其实现为基数排序:您可以使用带有适当比较器的比较排序算法。例如,在 C 中,以下内容适合与 qsort 一起使用(除非我把它搞砸了):
效率不是很高,因为它做了很多重复的工作,但很简单。
Edit: I missed that it's a contiguous range. That being the case, all the answers which talk about sorting an array are wrong (including your idea stated in the question that it's like a radix sort), and True Soft's answer is right.
just like Radix Sort but just that the digits are sorted in reversed order
Well spotted :-) If you actually do it that way, funnily enough, it's called an MSD radix sort.
http://en.wikipedia.org/wiki/Radix_sort#Most_significant_digit_radix_sorts
You can implement one very simply, or with a lot of high technology and fanfare. In most programming languages, your particular example faces a slight difficulty. Extracting decimal digits from the natural storage format of an integer, isn't an especially fast operation. You can ignore this and see how long it ends up taking (recommended), or you can add yet more fanfare by converting all the numbers to decimal strings before sorting.
Of course you don't have to implement it as a radix sort: you could use a comparison sort algorithm with an appropriate comparator. For example in C, the following is suitable for use with qsort (unless I've messed it up):
Not terribly efficient, since it does a lot of repeated work, but straightforward.
如果您不想将它们转换为字符串,但有足够的空间来存储列表的额外副本,我将存储副本中元素的十的最大幂。这可能是使用循环最容易做到的。现在调用您的原始数组
x
和 10 的幂y
。您也可以直接计算它们
,但我怀疑迭代可能比浮点转换更快。
为了比较第 i 个元素和第 j 个元素,
我们将较小的数字乘以适当的 10 次方,使这两个数字具有位数相等,然后进行比较。如果修改后的两个数字相等,则比较数字长度。
如果您没有空间来存储 y 数组,您可以在每次比较时计算它们。
一般来说,使用预先优化的数字转换例程可能会更好。
If you do not want to convert them to strings, but have enough space to store an extra copy of the list I would store the largest power of ten less than the element in the copy. This is probably easiest to do with a loop. Now call your original array
x
and the powers of teny
.You could also compute them directly
but I suspect that the iteration may be faster than the conversions to and from floating point.
In order to compare the
i
th andj
th elementsWhat is being done here is we are multiplying the smaller number by the appropriate power of ten to make the two numbers have an equal number of digits, then comparing them. if the two modified numbers are equal, then compare the digit lengths.
If you do not have the space to store the y arrays you can compute them on each comparison.
In general, you are likely better off using the preoptimized digit conversion routines.