2010-07-21 59 views
10

Cách hiệu quả nhất để chuyển đổi số số thành từ tiếng AnhThuật toán chuyển đổi số dạng số thành từ tiếng Anh

ví dụ: 12 đến mười hai 127 đến một trăm hai mươi bảy

+2

Hoặc bằng tiếng Anh một trăm ** và ** hai mươi bảy. :) –

+1

@Philip, "và" là sai nếu bạn đang nói về tiếng Anh thích hợp. "Và" là cho các phần phân đoạn. –

+1

@David - Bằng tiếng Anh, nếu một số bao gồm một số nhỏ hơn ** và ** gia nhập chúng. Như trong năm 2010 - hai nghìn lẻ mười. Một biến thể khác là tiền tệ khi £ 1,20 là một pound hai mươi hay một pound và hai mươi pence. Nếu bạn chán, bạn có thể xem http://www.english-at-home.com/speaking/saying-dates-and-numbers-in-english/ –

Trả lời

16

Điều đó không mất nhiều thời gian. Đây là một thực hiện được viết bằng Java.

http://snippets.dzone.com/posts/show/3685

public class IntToEnglish { 
    static String[] to_19 = { "zero", "one", "two", "three", "four", "five", "six", 
     "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", 
     "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" }; 
    static String[] tens = { "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"}; 
    static String[] denom = { "", 
     "thousand",  "million",   "billion",  "trillion",  "quadrillion", 
     "quintillion", "sextillion",  "septillion", "octillion",  "nonillion", 
     "decillion", "undecillion",  "duodecillion", "tredecillion", "quattuordecillion", 
     "sexdecillion", "septendecillion", "octodecillion", "novemdecillion", "vigintillion" }; 

    public static void main(String[] argv) throws Exception { 
     int tstValue = Integer.parseInt(argv[0]); 
     IntToEnglish itoe = new IntToEnglish(); 
     System.out.println(itoe.english_number(tstValue)); 
     /* for (int i = 0; i < 2147483647; i++) { 
      System.out.println(itoe.english_number(i)); 
     } */ 
    } 
    // convert a value < 100 to English. 
    private String convert_nn(int val) throws Exception { 
     if (val < 20) 
      return to_19[val]; 
     for (int v = 0; v < tens.length; v++) { 
      String dcap = tens[v]; 
      int dval = 20 + 10 * v; 
      if (dval + 10 > val) { 
       if ((val % 10) != 0) 
        return dcap + "-" + to_19[val % 10]; 
       return dcap; 
      }   
     } 
     throw new Exception("Should never get here, less than 100 failure"); 
    } 
    // convert a value < 1000 to english, special cased because it is the level that kicks 
    // off the < 100 special case. The rest are more general. This also allows you to 
    // get strings in the form of "forty-five hundred" if called directly. 
    private String convert_nnn(int val) throws Exception { 
     String word = ""; 
     int rem = val/100; 
     int mod = val % 100; 
     if (rem > 0) { 
      word = to_19[rem] + " hundred"; 
      if (mod > 0) { 
       word = word + " "; 
      } 
     } 
     if (mod > 0) { 
      word = word + convert_nn(mod); 
     } 
     return word; 
    } 
    public String english_number(int val) throws Exception { 
     if (val < 100) { 
      return convert_nn(val); 
     } 
     if (val < 1000) { 
      return convert_nnn(val); 
     } 
     for (int v = 0; v < denom.length; v++) { 
      int didx = v - 1; 
      int dval = new Double(Math.pow(1000, v)).intValue(); 
      if (dval > val) { 
       int mod = new Double(Math.pow(1000, didx)).intValue(); 
       int l = val/mod; 
       int r = val - (l * mod); 
       String ret = convert_nnn(l) + " " + denom[didx]; 
       if (r > 0) { 
        ret = ret + ", " + english_number(r); 
       } 
       return ret; 
      } 
     } 
     throw new Exception("Should never get here, bottomed out in english_number"); 
    } 
} 
2

Một cách để thực hiện điều này sẽ được sử dụng nhìn lên bảng. Nó sẽ có phần lực bạo lực, nhưng dễ cài đặt. Ví dụ, bạn có thể có từ 0-99 trong một bảng, sau đó một bảng cho hàng chục, hàng trăm, hàng nghìn, v.v. Một số phép tính đơn giản sẽ cho bạn chỉ mục từ bạn cần từ mỗi bảng.

+0

Đó sẽ là một sự lãng phí rất lớn của bộ nhớ. – Christian

+0

Tôi đồng ý với đánh giá của bạn nhưng tôi đã sử dụng thuật ngữ "brute force" trong mô tả của tôi. Ngoài ra, còn có các câu trả lời khác cho cùng câu hỏi này sử dụng phương pháp tìm kiếm bảng, bao gồm câu trả lời được chấp nhận. Tôi không chắc tại sao bình luận của bạn chỉ áp dụng cho câu trả lời của tôi. – nathan

1

.) Tạo một thư viện gồm tất cả các số & vị trí (ví dụ: 1 có ký hiệu khác hơn 10, khác 100) .) Liệt kê các ngoại lệ (ví dụ: 12) và lưu ý rằng ngoại lệ tương tự cho 112, 1012, v.v.

nếu bạn muốn tốc độ cao hơn, hãy tạo một bộ số lượng được lưu trong bộ nhớ cache mà bạn cần.

1

Lưu ý một số quy tắc:

số
  • Hàng chục (hai mươi, ba mươi, vv) kết thúc bằng y được tuân thủ bởi dấu gạch nối.
  • Thanh thiếu niên đặc biệt (trừ 15-19, nhưng chúng vẫn còn đặc biệt).
  • Mọi thứ khác chỉ là một số kết hợp của digit place như "ba nghìn".

Bạn có thể lấy vị trí của một số bằng cách sử dụng bộ phận sàn của các số nguyên: 532/100 -> 5

2

Đây là một số mã python cũ trên ổ cứng của tôi. Có thể có lỗi nhưng nó sẽ hiển thị ý tưởng cơ bản:

class Translator: 
    def transformInt(self, x): 
     translateNumbers(0,[str(x)]) 

    def threeDigitsNumber(self,number): 
     snumber=self.twoDigitsNumber(number/100) 
     if number/100!=0: 
      snumber+=" hundred " 
     snumber+self.twoDigitsNumber(number) 
     return snumber+self.twoDigitsNumber(number) 
    def twoDigitsNumber(self,number): 
     snumber="" 
     if number%100==10: 
      snumber+="ten" 
     elif number%100==11: 
      snumber+="eleven" 
     elif number%100==12: 
      snumber+="twelve" 
     elif number%100==13: 
      snumber+="thirteen" 
     elif number%100==14: 
      snumber+="fourteen" 
     elif number%100==15: 
      snumber+="fifteen" 
     elif number%100==16: 
      snumber+="sixteen" 
     elif number%100==17: 
      snumber+="seventeen" 
     elif number%100==18: 
      snumber+="eighteen" 
     elif number%100==19: 
      snumber+="nineteen" 
     else: 
      if (number%100)/10==2: 
       snumber+="twenty-" 
      elif (number%100)/10==3: 
       snumber+="thirty-" 
      elif (number%100)/10==4: 
       snumber+="forty-" 
      elif (number%100)/10==5: 
       snumber+="fifty-" 
      elif (number%100)/10==6: 
       snumber+="sixty-" 
      elif (number%100)/10==7: 
       snumber+="seventy-" 
      elif (number%100)/10==8: 
       snumber+="eighty-" 
      elif (number%100)/10==9: 
       snumber+="ninety-" 
      if (number%10)==1: 
       snumber+="one" 
      elif (number%10)==2: 
       snumber+="two" 
      elif (number%10)==3: 
       snumber+="three" 
      elif (number%10)==4: 
       snumber+="four" 
      elif (number%10)==5: 
       snumber+="five" 
      elif (number%10)==6: 
       snumber+="six" 
      elif (number%10)==7: 
       snumber+="seven" 
      elif (number%10)==8: 
       snumber+="eight" 
      elif (number%10)==9: 
       snumber+="nine" 
      elif (number%10)==0: 
       if snumber!="": 
        if snumber[len(snumber)-1]=="-": 
         snumber=snumber[0:len(snumber)-1] 
     return snumber 
    def translateNumbers(self,counter,words): 
     if counter+1<len(words): 
      self.translateNumbers(counter+1,words) 
     else: 
      if counter==len(words): 
       return True 
     k=0 
     while k<len(words[counter]): 
      if (not (ord(words[counter][k])>47 and ord(words[counter][k])<58)): 
       break 
      k+=1 
     if (k!=len(words[counter]) or k==0): 
      return 1 
     number=int(words[counter]) 
     from copy import copy 
     if number==0: 
      self.translateNumbers(counter+1,copy(words[0:counter]+["zero"]+words[counter+1:len(words)])) 
      self.next.append(copy(words[0:counter]+["zero"]+words[counter+1:len(words)])) 
      return 1 
     if number<10000: 
      self.translateNumbers(counter+1,copy(words[0:counter] 
                 +self.seperatewords(self.threeDigitsNumber(number)) 
                 +words[counter+1:len(words)])) 
      self.next.append(copy(words[0:counter] 
             +self.seperatewords(self.threeDigitsNumber(number)) 
             +words[counter+1:len(words)])) 
     if number>999: 
      snumber="" 
      if number>1000000000: 
       snumber+=self.threeDigitsNumber(number/1000000000)+" billion " 
       number=number%1000000000 
      if number>1000000: 
       snumber+=self.threeDigitsNumber(number/1000000)+" million " 
       number=number%1000000 
      if number>1000: 
       snumber+=self.threeDigitsNumber(number/1000)+" thousand " 
       number=number%1000 
      snumber+=self.threeDigitsNumber(number) 
      self.translateNumbers(counter+1,copy(words[0:counter]+self.seperatewords(snumber) 
                 +words[counter+1:len(words)])) 
      self.next.append(copy(words[0:counter]+self.seperatewords(snumber) 
             +words[counter+1:len(words)])) 
2

Giải pháp này không tính đến khoảng trắng ở cuối, nhưng nó khá nhanh.

typedef const char* cstring; 
using std::string; 
using std::endl; 
std::ostream& GetOnes(std::ostream &output, int onesValue) 
{ 
    cstring ones[] = { "zero", "one", "two", "three", "four", "five", "six", 
      "seven", "eight", "nine" }; 
    output << ones[onesValue]; 
    return output; 
} 

std::ostream& GetSubMagnitude(std::ostream &output, int subMagnitude) 
{ 
    cstring tens[] = { "zeroty", "ten", "twenty", "thirty", "fourty", "fifty", 
     "sixty", "seventy", "eighty", "ninety"}; 
    if (subMagnitude/100 != 0) 
    {  
     GetOnes(output, subMagnitude/100) << " hundred "; 
     GetSubMagnitude(output, subMagnitude - subMagnitude/100 * 100); 
    } 
    else 
    { 
     if (subMagnitude >= 20) 
     { 
      output << tens[subMagnitude/10] << " "; 
      GetOnes(output, subMagnitude - subMagnitude/10 * 10); 
     } 
     else if (subMagnitude >= 10) 
     { 
      cstring teens[] = { "ten", "eleven", "twelve", "thirteen", 
         "fourteen", "fifteen", "sixteen", "seventeen", 
         "eighteen", "nineteen" }; 
      output << teens[subMagnitude - 10] << " "; 
     } 
     else 
     { 
      GetOnes(output, subMagnitude) << " "; 
     } 
    } 
    return output; 
} 

std::ostream& GetLongNumber(std::ostream &output, double input) 
{ 
    cstring magnitudes[] = {"", "hundred", "thousand", "million", "billion", 
          "trillion"}; 
    double magnitudeTests[] = {1, 100.0, 1000.0, 1000000.0, 1000000000.0, 
          1000000000000.0 }; 
    int magTestIndex = 0; 
    while (floor(input/magnitudeTests[magTestIndex++]) != 0); 
    magTestIndex -= 2; 
    if (magTestIndex >= 0) 
    { 
     double subMagnitude = input/magnitudeTests[magTestIndex]; 
     GetSubMagnitude(output, (int)subMagnitude); 
     if (magTestIndex) { 
      output << magnitudes[magTestIndex] << " "; 
      double remainder = input - (floor(input/
         magnitudeTests[magTestIndex]) * 
         magnitudeTests[magTestIndex]); 
      if (floor(remainder) > 0) 
      { 
       GetLongNumber(output, remainder); 
      } 
     } 
    } 
    else 
    { 
     output << "zero"; 
    } 
    return output; 
} 
+0

Rõ ràng, từ chối trách nhiệm bao gồm rằng nó không chiếm số lớn hơn 999,999,999,999,999, nó không làm phân số và nó không xử lý số âm. Đủ dễ dàng để thêm, nhưng bạn phải dừng lại ở một số điểm. –

2

Bắt đầu bằng cách giải 1-99, sử dụng danh sách các số cho 1-20, sau đó thêm 30, 40, ..., 90. Sau đó, thêm hàng trăm để nhận 1-999. Sau đó, sử dụng thường trình đó để cung cấp số lượng của mỗi 1000 cho cao như bạn muốn đi (tôi nghĩ rằng danh pháp tiêu chuẩn cao nhất là cho decillion, đó là 10^33).

Một lưu ý nhỏ là có một chút khó khăn để có được khoảng trắng ngay trong mọi trường hợp nếu bạn đang cố bắt đầu và kết thúc mà không có khoảng trống thừa. Các giải pháp dễ dàng là để trống sau mỗi từ, và sau đó dải ra khỏi dấu trống khi bạn đang làm tất cả. Nếu bạn cố gắng chính xác hơn trong khi xây dựng chuỗi, bạn có thể kết thúc với khoảng trống thiếu hoặc khoảng trống thừa.

Các vấn đề liên quan