2010-04-01 42 views
13

Tôi có một số, nói "123456" và tôi cần ánh xạ nó thành chuỗi, bất kỳ chuỗi nào. Ràng buộc duy nhất về chức năng bản đồ là:Chuyển đổi một số thành chuỗi ký tự ngắn nhất có thể trong khi duy trì tính duy nhất

  • mỗi số phải ánh xạ vào một chuỗi ký tự duy nhất (điều này có nghĩa các chuỗi có thể được tùy tiện lâu)
  • chuỗi ký tự chỉ có thể chứa 0-9, az, AZ

Chức năng bản đồ nào sẽ tạo ra các chuỗi ngắn nhất?

Các giải pháp trong JavaScript được ưu tiên.

Lưu ý: Rõ ràng giải pháp đơn giản nhất là sử dụng số gốc, vì vậy hãy đảm bảo rằng giải pháp của bạn hoạt động tốt hơn.

+0

Bạn nói "danh sách chữ số" thay vì "số". Điều này có nghĩa là bạn muốn "000006" được xử lý khác với "6"? – AakashM

+0

Một câu hỏi hay. Không, tôi không. Tôi sẽ sửa nó để làm cho nó rõ ràng hơn. – alumb

Trả lời

30

Bạn có thể muốn sử dụng Cơ sở 36 hoặc Cơ sở 62.

Cơ sở 36 sẽ là gọn nhẹ nhất cho các ký tự chữ và số không phân biệt dạng chữ, nhưng nếu bạn muốn khai thác phân biệt chữ hoa chữ thường, Base 62 sẽ nhỏ hơn khoảng 20%.

Đối với cơ sở 36, bạn có thể dễ dàng sử dụng phương thức JavaScript của Number.toString(radix), như sau:

var n = 123456; 
n.toString(36); // returns: "2n9c" 

Đối với cơ sở 62, bạn có thể muốn kiểm tra this forum post. Về cơ bản, bạn có thể thực hiện những việc sau:

Number.prototype.toBase = function (base) { 
    var symbols = 
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); 
    var decimal = this; 
    var conversion = ""; 

    if (base > symbols.length || base <= 1) { 
     return false; 
    } 

    while (decimal >= 1) { 
     conversion = symbols[(decimal - (base * Math.floor(decimal/base)))] + 
        conversion; 
     decimal = Math.floor(decimal/base); 
    } 

    return (base < 11) ? parseInt(conversion) : conversion; 
} 

var n = 123456; 
n.toBase(62); // returns: "w7e" 
+0

Trừ khi tôi bị nhầm lẫn, OP yêu cầu cơ sở 62. – spender

+0

@spender: Có, bạn nói đúng, vì A-Z đã được đề cập rõ ràng. Đã sửa đổi câu trả lời của tôi. –

+0

123456.toString (36) đáp ứng các yêu cầu ... quá tệ nó không làm cơ sở 62, điều đó sẽ tốt hơn. – alumb

0

Tôi đã tạo điều này để tạo các khóa tương tự trên YouTube. Nó sử dụng regex để nắm bắt số và sau đó chu kỳ trên một danh sách phù hợp để lắp ráp chuỗi.

Thứ tự của mảng ký tự là tùy ý, bạn có thể thực hiện bất kỳ thứ gì bạn thích, nhưng khi bạn đã đặt nó vào vị trí, không thay đổi sau, nếu không bạn có thể chạy vào các khóa trùng lặp và đảm bảo bạn không không có bất kỳ bản sao nào.

Ở đây, num, là biến chứa khóa nhập. Nó rất dài trong mẫu này, nhưng nó có thể dài bất kỳ.

var chars = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"] 
num = "000102030405060708091011121314151617181920212223242526272829303132333435373839404142434445464748495051525354555657585960616263646566"; 
getnums = num.match(/(0|6[0-1]|[0-5]?[0-9])/g); 
to62 = ""; 
for (var i=0;i<getnums.length;i++) { 
    to62 = to62 + chars[parseInt(getnums[i])]; 
    // console.log(getnums[i] + ": " + chars[parseInt(getnums[i])]) 
} 
console.log(to62); 

Và đây là triển khai trong Cold Fusion sử dụng mảng dựa trên 1 chứ không phải mảng 0 dựa trên javascript, trong trường hợp nó giúp mọi người.

<cfscript> 
    chars = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]; 
    num = "0001020304050607080910111213141516171819202122232425262728293031323334353738394041424344454614748495051525354555657585960616263646566"; 
    getnums = ReMatch("(0|6[0-1]|[0-5]?[0-9])",num); 
    to62 = ""; 
    for (i=1; i<=arraylen(getnums); i=i+1) { 
     to62 = to62 & chars[getnums[i]+1]; 
    } 
    writeoutput(to62); 
</cfscript> 
Các vấn đề liên quan