如何对罗马数字数组进行排序? [英] How to sort an array of Roman numerals?

查看:463
本文介绍了如何对罗马数字数组进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组,其中包含罗马数字 (作为字符串课程).像这样:

I have an array containing Roman numerals (as strings of course). Like this:

 $a = array('XIX', 'LII', 'V', 'MCCXCIV', 'III', 'XIII');

我想根据这些数字的数字对它们进行排序,因此结果应类似于:

I'd like to sort them according to the numeric values of these numerals, so the results should be something like:

 $sorted_a = array('III', 'V', 'XIII', 'XIX', 'LII', 'MCCXCIV');

所以我的问题是:对罗马数字数组进行排序的最佳方法是什么?我知道如何使用PHP的数组排序功能,我对比较功能内部的逻辑很感兴趣.

So my question is: what is the best way to sort an array of Roman numerals? I know how to use the array sorting functions of PHP, I'm interested in the logic that goes on inside the comparison function.

编辑:为简单起见,我只想寻找一种以标准方式处理由基本数字构成的字符串的方式(例如,没有CCCC):

EDIT: For simplicity, I'm only looking for a way that deals with strings constructed of the basic numerals in a standard way (no CCCC for example):

I, V, X, L, C, D, M


测试结果

我花了很多时间来测试所有已发布的代码示例.进行了两项测试,一项带有20个罗马数字的随机数组,另一项带有包含4000个罗马数字的数组.同一台机器,很多次迭代,平均花费的时间,所有这些都运行了好几次. 当然,这没什么特别的,只是我自己的测试.

I took the time to extensively test all the code examples that were posted. Two tests were taken, one with a random array of 20 Roman numerals, and a second with an array containing 4000 of those. Same machine, lot of iterations, an average time taken, and all this run several times. Of course this is nothing offical, just my own tests.

具有20个数字的测试:

  1. hakre bazmegakapa -大约0.0005 s
  2. 反抗安德里亚德克·麦克Quickly -大约0.0010 s
  3. 乔·尼尔森-约0.0050 s
  4. Rob Hruska -约0.0100 s
  1. hakre, bazmegakapa - around 0.0005 s
  2. anemgyenge, Andrea, Dirk McQuickly - around 0.0010 s
  3. Joe Nelson - around 0.0050 s
  4. Rob Hruska - around 0.0100 s

具有4000个数字的测试:

  1. hakre bazmegakapa -大约0.13 s
  2. 反击-大约1.4 s
  3. Dirk McQuickly Andrea -大约1.8 s
  4. Rob Hruska -大约2.8秒
  5. 乔·纳尔逊-大约15 s(惊喜,再检查几次)
  1. hakre, bazmegakapa - around 0.13 s
  2. anemgyenge - around 1.4 s
  3. Dirk McQuickly, Andrea - around 1.8 s
  4. Rob Hruska - around 2.8 s
  5. Joe Nelson - around 15 s (surprise, checked several more times)

我很难授予赏金. hakre和我按照相同的路线制作了最快的版本,但是他对我的版本进行了修改,该修改以前是基于borrible的想法的.因此,我将接受hakre的解决方案,因为这是比我的(IMO)最快,更好的解决方案.但是我将赏赐给anemgyenge,因为我喜欢他的版本,而且似乎付出了很多努力.

I have a hard time awarding the bounty. hakre and I made the fastest versions, following the same route, but he made a variation of mine, which was previously based on borrible's idea. So I will accept hakre's solution, because that is the quickest and nicer than mine (IMO). But I will award the bounty to anemgyenge, because I love his version and a lot of effort seems to be put into it.

推荐答案

选择

Picking your class to convert roman numbers to integers, a user-defined sort callback can handle this to sort the array:

$a = array('XIX', 'LII', 'V', 'MCCXCIV', 'III', 'XIII');

$bool = usort($a, function($a, $b) {
    return RomanNumber::Roman2Int($a) - RomanNumber::Roman2Int($b);
});    
var_dump($a);

因此,在这里您可以找到比较函数内部的逻辑:如果两个值的权重相同,则返回0.如果第一个小于第二个,则返回< 0(例如-1),否则第二个大于第一个,因此返回> 0(例如1).

So here you find the logic inside the comparison function: if both values are of the same weight, return 0. If the first is lower than the second, return < 0 (e.g. -1), otherwise the second is larger than the first so return > 0 (e.g. 1).

自然,返回罗马数字十进制值的任何其他类型的函数也可以工作.

Naturally any other type of function that returns the decimal value for a roman number would work as well.

正如您所评论的,您不想为每对运行转换.很好,借助包含所有已转换值的附加数组,您可以对十进制值运行排序,也可以对罗马数字进行排序(

As you commented, you do not want to run the conversion for each pair. That's fine, with a help of an additional array which contains all converted values, you can run the sort on the decimal values and use that sorting on the roman numbers as well (Demo):

$a = array('XIX', 'LII', 'V', 'MCCXCIV', 'III', 'XIII');
$b = array_map('RomanNumber::Roman2Int', $a);
array_multisort($b, $a);
var_dump($a);

> array_multisort PHP手册 在这里完成了大部分魔术工作.

array_multisort PHP Manual does most of the magic here.

这篇关于如何对罗马数字数组进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆