Java中有没有一种方法可以将整数转换为其序号名称?

Java中有没有一种方法可以将整数转换为其序号名称?,java,Java,我想取一个整数并得到它的序号,即: 1 -> "First" 2 -> "Second" 3 -> "Third" ... 如果您对1st、2nd、3rd等都满意,下面是一些可以正确处理任何整数的简单代码: public static String ordinal(int i) { String[] suffixes = new String[] { "th", "st", "nd", "rd&qu

我想取一个整数并得到它的序号,即:

1 -> "First"
2 -> "Second"
3 -> "Third"
...

如果您对
1st
2nd
3rd
等都满意,下面是一些可以正确处理任何整数的简单代码:

public static String ordinal(int i) {
    String[] suffixes = new String[] { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" };
    switch (i % 100) {
    case 11:
    case 12:
    case 13:
        return i + "th";
    default:
        return i + suffixes[i % 10];

    }
}
以下是一些针对边缘情况的测试:

public static void main(String[] args) {
    int[] tests = {0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 100, 101, 102, 103, 104, 111, 112, 113, 114, 1000};
    for (int test : tests) {
        System.out.println(ordinal(test));
    }
}
输出:

0th
1st
2nd
3rd
4th
5th
10th
11th
12th
13th
14th
20th
21st
22nd
23rd
24th
100th
101st
102nd
103rd
104th
111th
112th
113th
114th
1000th
第1行:

public static String ordinal(int i) {
    return i % 100 == 11 || i % 100 == 12 || i % 100 == 13 ? i + "th" : i + new String[]{"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"}[i % 10];
}
另一个解决方案

public static String ordinal(int i) {
    int mod100 = i % 100;
    int mod10 = i % 10;
    if(mod10 == 1 && mod100 != 11) {
        return i + "st";
    } else if(mod10 == 2 && mod100 != 12) {
        return i + "nd";
    } else if(mod10 == 3 && mod100 != 13) {
        return i + "rd";
    } else {
        return i + "th";
    }
}
Pro:不需要初始化数组(减少垃圾)
缺点:不是一行一行的…

使用优秀的(还有一个优秀的C版本),你也可以这样做,把序数作为简单的单词

RuleBasedNumberFormat nf = new RuleBasedNumberFormat(Locale.UK, RuleBasedNumberFormat.SPELLOUT);
for(int i = 0; i <= 30; i++)
{
    System.out.println(i + " -> "+nf.format(i, "%spellout-ordinal"));
}

最好、最简单的方法是:

import java.util.*;
public class Numbers 
{
    public final static String print(int num)
    {
        num = num%10;
        String str = "";
        switch(num)
        {
        case 1:     
            str = "st";
            break;
        case 2:     
            str = "nd";
            break;
        case 3:     
            str = "rd";
            break;
        default: 
            str = "th";             
        }
        return str;
    }

    public static void main(String[] args) 
    {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter a number: ");
        int number = sc.nextInt();
        System.out.print(number + print(number));
    }
}

波西米亚人的回答很好,但我建议改进错误处理。对于ordinal的原始版本,如果提供负整数,将抛出ArrayIndexOutOfBoundsException。我认为我下面的说法更清楚。我希望junit也很有用,因此无需目视检查输出

public class FormattingUtils {

    /**
     * Return the ordinal of a cardinal number (positive integer) (as per common usage rather than set theory).
     * {@link http://stackoverflow.com/questions/6810336/is-there-a-library-or-utility-in-java-to-convert-an-integer-to-its-ordinal}
     * 
     * @param i
     * @return
     * @throws {@code IllegalArgumentException}
     */
    public static String ordinal(int i) {
        if (i < 0) {
            throw new IllegalArgumentException("Only +ve integers (cardinals) have an ordinal but " + i + " was supplied");
        }

        String[] sufixes = new String[] { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" };
        switch (i % 100) {
        case 11:
        case 12:
        case 13:
            return i + "th";
        default:
            return i + sufixes[i % 10];
        }
    }
}


import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;

public class WhenWeCallFormattingUtils_Ordinal {

    @Test
    public void theEdgeCasesAreCovered() {
        int[] edgeCases = { 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 100, 101, 102, 103, 104, 111, 112,
                113, 114 };
        String[] expectedResults = { "0th", "1st", "2nd", "3rd", "4th", "5th", "10th", "11th", "12th", "13th", "14th",
                "20th", "21st", "22nd", "23rd", "24th", "100th", "101st", "102nd", "103rd", "104th", "111th", "112th",
                "113th", "114th" };

        for (int i = 0; i < edgeCases.length; i++) {
            assertThat(FormattingUtils.ordinal(edgeCases[i])).isEqualTo(expectedResults[i]);
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void supplyingANegativeNumberCausesAnIllegalArgumentException() {
        FormattingUtils.ordinal(-1);
    }

}
公共类格式化utils{
/**
*返回基数(正整数)的序号(根据常用用法而不是集合论)。
*{@linkhttp://stackoverflow.com/questions/6810336/is-there-a-library-or-utility-in-java-to-convert-an-integer-to-its-ordinal}
* 
*@param i
*@返回
*@throws{@code IllegalArgumentException}
*/
公共静态字符串序号(int i){
if(i<0){
抛出新的IllegalArgumentException(“只有+ve个整数(基数)有序号,但提供了“+i+”);
}
字符串[]sufixes=新字符串[]{“th”、“st”、“nd”、“rd”、“th”、“th”、“th”、“th”、“th”、“th”、“th”};
开关(i%100){
案例11:
案例12:
案例13:
返回i+“th”;
违约:
返回i+sufixes[i%10];
}
}
}
导入org.junit.Test;
导入静态org.assertj.core.api.Assertions.assertThat;
按顺序调用时的公共类{
@试验
公开作废案件记录(){
int[]edgeCases={0,1,2,3,4,5,10,11,12,13,14,20,21,22,23,24,100,101,102,103,104,111,112,
113, 114 };
字符串[]expectedResults={“0”、“1”、“2”、“3”、“4”、“5”、“10”、“11”、“12”、“13”、“14”,
“20、21、22、23、24、100、101、102、103、104、111、112”,
“113”、“114”};
对于(int i=0;i
在Scala中进行更改

List(1, 2, 3, 4, 5, 10, 11, 12, 13, 14 , 19, 20, 23, 33, 100, 113, 123, 101, 1001, 1011, 1013, 10011) map {
    case a if (a % 10) == 1 && (a % 100) != 11 => a + "-st"
    case b if (b % 10) == 2 && (b % 100) != 12 => b + "-nd"
    case c if (c % 10) == 3 && (c % 100) != 13 => c + "-rd"
    case e                                     => e + "-th"
  }  foreach println

我有一个很长很复杂但很容易理解的概念

private static void convertMe() {

    Scanner in = new Scanner(System.in);
    try {
        System.out.println("input a number to convert: ");
        int n = in.nextInt();

        String s = String.valueOf(n);
        //System.out.println(s);

        int len = s.length() - 1;
        if (len == 0){
            char lastChar = s.charAt(len);
            if (lastChar == '1'){
                System.out.println(s + "st");
            } else if (lastChar == '2') {
                System.out.println(s + "nd");
            } else if (lastChar == '3') {
                System.out.println(s + "rd");
            } else {
                System.out.println(s + "th");
            }
        } else if (len > 0){
            char lastChar = s.charAt(len);
            char preLastChar = s.charAt(len - 1);
            if (lastChar == '1' && preLastChar != '1'){ //not ...11
                System.out.println(s + "st");
            } else if (lastChar == '2' && preLastChar != '1'){ //not ...12
                System.out.println(s + "nd");
            } else if (lastChar == '3' && preLastChar != '1'){ //not ...13
                System.out.println(s + "rd");
            } else {
                System.out.println(s + "th");
            }
        }


    } catch(InputMismatchException exception){
        System.out.println("invalid input");
    }


}

我已经用一种非常简单的方式弄明白了如何在Android中实现这一点。您只需将依赖项添加到
应用程序的
build.gradle
文件:

implementation "com.ibm.icu:icu4j:53.1"
接下来,创建此方法:

Kotlin:

fun Number?.getOrdinal(): String? {
    if (this == null) {
        return null
    }

    val format = "{0,ordinal}"

    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        android.icu.text.MessageFormat.format(format, this)
    } else {
        com.ibm.icu.text.MessageFormat.format(format, this)
    }
}
public static String getNumberOrdinal(Number number) {
        if (number == null) {
            return null;
        }

        String format = "{0,ordinal}";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return android.icu.text.MessageFormat.format(format, number);
        } else {
            return com.ibm.icu.text.MessageFormat.format(format, number);
        }
    }
val ordinal = 2.getOrdinal()
String ordinal = getNumberOrdinal(2)
Java:

fun Number?.getOrdinal(): String? {
    if (this == null) {
        return null
    }

    val format = "{0,ordinal}"

    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        android.icu.text.MessageFormat.format(format, this)
    } else {
        com.ibm.icu.text.MessageFormat.format(format, this)
    }
}
public static String getNumberOrdinal(Number number) {
        if (number == null) {
            return null;
        }

        String format = "{0,ordinal}";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return android.icu.text.MessageFormat.format(format, number);
        } else {
            return com.ibm.icu.text.MessageFormat.format(format, number);
        }
    }
val ordinal = 2.getOrdinal()
String ordinal = getNumberOrdinal(2)
然后,您可以这样简单地使用它:

Kotlin:

fun Number?.getOrdinal(): String? {
    if (this == null) {
        return null
    }

    val format = "{0,ordinal}"

    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        android.icu.text.MessageFormat.format(format, this)
    } else {
        com.ibm.icu.text.MessageFormat.format(format, this)
    }
}
public static String getNumberOrdinal(Number number) {
        if (number == null) {
            return null;
        }

        String format = "{0,ordinal}";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return android.icu.text.MessageFormat.format(format, number);
        } else {
            return com.ibm.icu.text.MessageFormat.format(format, number);
        }
    }
val ordinal = 2.getOrdinal()
String ordinal = getNumberOrdinal(2)
Java:

fun Number?.getOrdinal(): String? {
    if (this == null) {
        return null
    }

    val format = "{0,ordinal}"

    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        android.icu.text.MessageFormat.format(format, this)
    } else {
        com.ibm.icu.text.MessageFormat.format(format, this)
    }
}
public static String getNumberOrdinal(Number number) {
        if (number == null) {
            return null;
        }

        String format = "{0,ordinal}";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return android.icu.text.MessageFormat.format(format, number);
        } else {
            return com.ibm.icu.text.MessageFormat.format(format, number);
        }
    }
val ordinal = 2.getOrdinal()
String ordinal = getNumberOrdinal(2)
它的工作原理

从安卓N(API 24)开始,安卓使用
icu.text
,而不是常规的
java.text
(),后者已经包含了针对的国际化实现。因此解决方案显然很简单-将
icu4j
库添加到项目中,并在
Nougat

静态字符串getOrdinal(int-input)下面的版本中使用它{
static String getOrdinal(int input) {
    if(input<=0) {
        throw new IllegalArgumentException("Number must be > 0");
    }
    int lastDigit = input % 10;
    int lastTwoDigit = input % 100;
    if(lastTwoDigit >= 10 && lastTwoDigit <= 20) {
        return input+"th";
    }
    switch (lastDigit) {
    case 1:
        return input+"st";
    case 2:
        return input+"nd";
    case 3:
        return input+"rd";

    default:
        return input+"th";
    }
}

如果(input=10&&lastTwoDigit如果它也可以做前缀,那就太好了……st,nd,R注意,如果你想让你的程序在你自己的国家以外使用,你应该小心使用一个可以本地化的解决方案。如果你需要本地化,请看下面的@jfk答案。男孩,这会给垃圾收集器带来乐趣吗XD@Supuhstar,数组i它很容易被证明无法离开该方法的范围,因此编译器和运行时可以对此进行大量优化。即使我最悲观的预测是,该方法在很短的时间内不会产生任何垃圾。@M.Prokhorov我希望解决方案不依赖可能在版本和版本之间更改的JVM实现细节环境,而不是严格定义的语言行为t@Supuhstar,Java中关于垃圾的任何讨论都依赖于JVM实现细节。Java只定义了超出范围的对象被垃圾收集。它没有定义影响应用程序性能的垃圾对象的任何概念,也没有提到避免因此创建对象。@M.Prokhorov对,这就是为什么我认为将数组作为一个静态变量,保证在应用程序的整个生命周期中与任何JVM都在范围内,从而保证永远不会被车库收集,性能更可靠的原因。我没有看到这个处理数字11、12和13?我没有看到这个处理数字11、12和13d 13?使用和检查它们是否存在,例如-
if(number>=11&&number问Java的问题?我认为这应该被选为可接受的答案,因为它直接回答了问题。注意,对于某些语言,如意大利语,不存在%拼写顺序,必须在%拼写顺序阳性和%拼写顺序阴性之间进行选择,可能是某些语言有更多的genresThis很好,但是…我不完全相信库是如何从区域设置的角度处理事情的。这个答案中的示例代码说它使用了英国区域设置,但它给出了(例如)
壹万壹仟叁佰捌拾贰
对于数字
101382
。我希望它是
壹万壹仟叁佰捌拾贰
(加上那些“和”)。这(我认为)对英国来说更自然。这感觉更像是美国地区写单词的方式