2011-07-24 7 views
33

voglio prendere un intero e ottenere il suo ordinale, cioè .:Esiste un modo in Java per convertire un intero nel suo ordinale?

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

http: // StackOverflow .com/questions/3911966/how-to-convert-number-to-words-in-java – Felix

+1

Sarebbe bello se potrebbe fare anche i prefissi ... st, nd, rd –

+0

Nota che se vuoi che il tuo programma venga usato al di fuori del tuo paese, devi fare attenzione a usare una soluzione che possa essere localizzata. –

risposta

81

Se sei OK con "prima", "2 °", "3 °", ecc, ecco qualche semplice codice che gestire correttamente qualsiasi numero intero:

public static String ordinal(int i) { 
    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]; 

    } 
} 

Ecco alcuni test per casi limite:

public static void main(String[] args) { 
    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 }; 
    for (int edgeCase : edgeCases) { 
     System.out.println(ordinal(edgeCase)); 
    } 
} 

uscita:

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 
4

in linea 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]; 
} 
+1

Boy che darà al garbage collector un momento divertente XD – Supuhstar

+0

@Supuhstar, l'array si dimostra facilmente incapace di lasciare l'ambito di quel metodo, quindi il compilatore e il runtime possono fare ottimizzazioni piuttosto pesanti su questo.Anche con la mia previsione più pessimistica, questo metodo non produrrà alcuna spazzatura dopo poco tempo. –

+0

@ M.Prokhorov Preferirei una soluzione che non si basasse sui dettagli di implementazione JVM che potrebbero cambiare tra versioni e ambienti, ma invece su un comportamento linguistico rigorosamente definito che non è – Supuhstar

12

Un'altra soluzione

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: non richiede una matrice da inizializzare (meno spazzatura)
Contro: non una battuta ...

14

Utilizzando l'eccellente ICU4J (c'è anche una versione C eccellente) puoi anche fare questo e ottenere gli ordinali come parole semplici;

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

per esempio produce

0 -> zeroth 
1 -> first 
2 -> second 
3 -> third 
4 -> fourth 
5 -> fifth 
6 -> sixth 
7 -> seventh 
8 -> eighth 
9 -> ninth 
10 -> tenth 
11 -> eleventh 
12 -> twelfth 
13 -> thirteenth 
14 -> fourteenth 
15 -> fifteenth 
16 -> sixteenth 
17 -> seventeenth 
18 -> eighteenth 
19 -> nineteenth 
20 -> twentieth 
21 -> twenty-first 
22 -> twenty-second 
23 -> twenty-third 
24 -> twenty-fourth 
25 -> twenty-fifth 
26 -> twenty-sixth 
27 -> twenty-seventh 
28 -> twenty-eighth 
29 -> twenty-ninth 
30 -> thirtieth 
+3

Penso che questo avrebbe dovuto essere scelto come risposta accettata in quanto rispondeva direttamente alla domanda. – TheGT

-1

modo migliore e più semplice, qui andiamo:

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)); 
    } 
} 
+1

Non vedo questi numeri di gestione 11, 12 e 13? – Enoobong

2

Bohemians risposta è molto buona, ma vi consiglio di migliorare la gestione degli errori. Con la versione originale di ordinale se si fornisce un numero intero negativo verrà generata una ArrayIndexOutOfBoundsException. Penso che la mia versione di seguito sia più chiara. Spero che anche la junit sia utile quindi non è necessario controllare visivamente l'output.

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); 
    } 

} 
0

In Scala per un cambiamento,

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 
+0

La domanda ha chiesto di Java? – Enoobong

0
public static String getOrdinalFor(int value) { 
     int tenRemainder = value % 10; 
     switch (tenRemainder) { 
      case 1: 
      return value+"st"; 
      case 2: 
      return value+"nd"; 
      case 3: 
      return value+"rd"; 
      default: 
      return value+"th"; 
     } 
     } 
+0

Non vedo questi numeri di gestione 11, 12 e 13? Utilizzare e se controllarli, ad es. - '' if (numero> = 11 && numero <= 13) { numero di ritorno + "th"; } '' ' – Enoobong

-1
private static String getOrdinalIndicator(int number) { 
     int mod = number; 
     if (number > 13) { 
      mod = number % 10; 
     } 
     switch (mod) { 
     case 1: 
      return "st"; 
     case 2: 
      return "nd"; 
     case 3: 
      return "rd"; 
     default: 
      return "th"; 
     } 
    } 
+0

La domanda era di restituire' Primo' per 1 e così via come 'Eleventh' per 11 ecc. La tua risposta non lo raggiunge. –

0

ho avuto un lungo, complicato ma facile da capire il concetto

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"); 
    } 


} 
Problemi correlati