2012-06-30 28 views
7

Sono sicuro che questo è stato fatto centinaia di volte, ma spero che ci sia un modo davvero semplice per ottenere questo risultato. Sto volendo cambiare le parole in un int.Converti parole (stringa) in Int

Come il seguente esempio

One = 1 
Two = 2 
Three = 3 

Quindi, in pratica, se ho la stringa "One" che viene convertito in 1, anche se potessi tornare indietro una stringa "1" posso solo convertire tale.

+3

Quanti numeri avete bisogno di sostegno? 10 o più? – gdoron

+0

Beh, sostanzialmente tutti i numeri come se avessi centomilaseicento –

+0

http://www.daniweb.com/software-development/csharp/threads/209656/convert-words-into-numeri – JDPeckham

risposta

19

ha fatto questo per divertimento ... c'è probabilmente molti casi limite che avrebbe fallito ...

private static Dictionary<string,long> numberTable= 
    new Dictionary<string,long> 
     {{"zero",0},{"one",1},{"two",2},{"three",3},{"four",4}, 
     {"five",5},{"six",6},{"seven",7},{"eight",8},{"nine",9}, 
     {"ten",10},{"eleven",11},{"twelve",12},{"thirteen",13}, 
     {"fourteen",14},{"fifteen",15},{"sixteen",16}, 
     {"seventeen",17},{"eighteen",18},{"nineteen",19},{"twenty",20}, 
     {"thirty",30},{"forty",40},{"fifty",50},{"sixty",60}, 
     {"seventy",70},{"eighty",80},{"ninety",90},{"hundred",100}, 
     {"thousand",1000},{"million",1000000},{"billion",1000000000}, 
     {"trillion",1000000000000},{"quadrillion",1000000000000000}, 
     {"quintillion",1000000000000000000}}; 
public static long ToLong(string numberString) 
{ 
    var numbers = Regex.Matches(numberString, @"\w+").Cast<Match>() 
     .Select(m => m.Value.ToLowerInvariant()) 
     .Where(v => numberTable.ContainsKey(v)) 
     .Select(v => numberTable[v]); 
    long acc = 0,total = 0L; 
    foreach(var n in numbers) 
    { 
     if(n >= 1000) 
     { 
      total += (acc * n); 
      acc = 0; 
     } 
     else if(n >= 100){ 
      acc *= n; 
     } 
     else acc += n;   
    } 
    return (total + acc) * (numberString.StartsWith("minus", 
      StringComparison.InvariantCultureIgnoreCase) ? -1 : 1); 
} 
+0

Perché hai il doppio 'continua;'? Potresti semplicemente usare 'else's. (e +1, ovviamente.) – Ryan

+2

Sì, concordo ... meglio con le istruzioni else (e riduce anche la dimensione del codice e soddisfa la mia ossessione OCD con non avere barre di scorrimento nella mia risposta !!!) – spender

+0

Nota che 'il rapido brown fox' e 'zero' restituiscono entrambi' 0'. –

11

Ecco un metodo che lo fa. Se hai bisogno di una gamma più ampia, è facilmente estensibile; è sufficiente utilizzare uno long, uno o anche uno BigInt e aggiungere altri elementi al dizionario modifiers.

static int ParseEnglish(string number) { 
    string[] words = number.ToLower().Split(new char[] {' ', '-', ','}, StringSplitOptions.RemoveEmptyEntries); 
    string[] ones = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}; 
    string[] teens = {"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}; 
    string[] tens = {"ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"}; 
    Dictionary<string, int> modifiers = new Dictionary<string, int>() { 
     {"billion", 1000000000}, 
     {"million", 1000000}, 
     {"thousand", 1000}, 
     {"hundred", 100} 
    }; 

    if(number == "eleventy billion") 
     return int.MaxValue; // 110,000,000,000 is out of range for an int! 

    int result = 0; 
    int currentResult = 0; 
    int lastModifier = 1; 

    foreach(string word in words) { 
     if(modifiers.ContainsKey(word)) { 
      lastModifier *= modifiers[word]; 
     } else { 
      int n; 

      if(lastModifier > 1) { 
       result += currentResult * lastModifier; 
       lastModifier = 1; 
       currentResult = 0; 
      } 

      if((n = Array.IndexOf(ones, word) + 1) > 0) { 
       currentResult += n; 
      } else if((n = Array.IndexOf(teens, word) + 1) > 0) { 
       currentResult += n + 10; 
      } else if((n = Array.IndexOf(tens, word) + 1) > 0) { 
       currentResult += n * 10; 
      } else if(word != "and") { 
       throw new ApplicationException("Unrecognized word: " + word); 
      } 
     } 
    } 

    return result + currentResult * lastModifier; 
}