2010-08-26 65 views

回答

4

Joel Mueller's answer應該引導你的基礎-64的情況下。

針對您在your own answer提供的初步代碼,你絕對可以通過改變代碼來完成你的for循環做提高效率(有效的O(N)IndexOf)使用哈希查找(這應該使它成爲O(1))。

我基於這個假設baseChars是您在您的類的構造函數中初始化的字段。如果這是正確的,做如下調整:在你的StringToInt方法

private Dictionary<char, int> baseChars; 

// I don't know what your class is called. 
public MultipleBaseNumberFormatter(IEnumerable<char> baseCharacters) 
{ 
    // check for baseCharacters != null and Count > 0 

    baseChars = baseCharacters 
     .Select((c, i) => new { Value = c, Index = i }) 
     .ToDictionary(x => x.Value, x => x.Index); 
} 

然後:

char next = encodedString[currentChar]; 

// No enumerating -- we've gone from O(N) to O(1)! 
if (!characterIndices.TryGetValue(next, out nextCharIndex)) 
{ 
    throw new ArgumentException("Input includes illegal characters."); 
} 
+0

使用字典是一個好主意。 – ashes999 2010-08-27 16:41:59

2

我在這裏有一個工作版本的第一遍,儘管我不知道它有多高效。

public static int StringToInt(string encodedString) 
    { 
     int result = 0; 
     int sourceBase = baseChars.Length; 
     int nextCharIndex = 0; 

     for (int currentChar = encodedString.Length - 1; currentChar >= 0; currentChar--) 
     { 
      char next = encodedString[currentChar]; 

      // For loop gets us: baseChar.IndexOf(char) => int 
      for (nextCharIndex = 0; nextCharIndex < baseChars.Length; nextCharIndex++) 
      { 
       if (baseChars[nextCharIndex] == next) 
       { 
        break; 
       } 
      } 

      // For character N (from the end of the string), we multiply our value 
      // by 64^N. eg. if we have "CE" in hex, F = 16 * 13. 
      result += (int)Math.Pow(baseChars.Length, encodedString.Length - 1 - currentChar) * nextCharIndex; 
     } 

     return result; 
    } 
0

如果base-64真的是你需要的東西,而不是「任何基地」,那麼你需要的是已經內置到框架中的一切:

int orig = 1337; 
byte[] origBytes = BitConverter.GetBytes(orig); 
string encoded = Convert.ToBase64String(origBytes); 
byte[] decoded = Convert.FromBase64String(encoded); 
int converted = BitConverter.ToInt32(decoded, 0); 
System.Diagnostics.Debug.Assert(orig == converted); 
+0

神那醜不知道爲什麼人們狂歡這麼多關於這個C#。 – ldog 2010-08-26 23:00:59

+1

@ldog:哈哈,我無法想象任何曾經嘲笑過C#的人都會選擇*將字符串轉換爲整數作爲任意鹼基*作爲它真正閃耀的場景。事實上,將C#與C進行比較對我來說似乎毫無意義。假設我抱怨在C中快速開發一個豐富的GUI應用程序是多麼困難,並問爲什麼有人喜歡它。 – 2010-08-26 23:20:13

+0

它看起來不像是在工作。原始函數將(1,2,3,4)映射到(b,c,d,e);這個將它們映射到(AqAAAA,AgAAAA,AwAAAA,BAAAAA)。不是最初的意圖,即使用較少的字符數字。 – ashes999 2010-08-27 16:39:29

2

下面是使用LINQ的功能和.NET Framework 4.0 zip擴展進行計算的一個版本。

public static int StringToInt(string encodedString, char[] baseChars) { 
    int sourceBase = baseChars.Length; 

    var dict = baseChars 
     .Select((c, i) => new { Value = c, Index = i }) 
     .ToDictionary(x => x.Value, x => x.Index); 

    return encodedString.ToCharArray() 
     // Get a list of positional weights in descending order, calcuate value of weighted position 
     .Zip(Enumerable.Range(0,encodedString.Length).Reverse(), (f,s) => dict[f] * (int)Math.Pow(sourceBase,s)) 
     .Sum(); 
} 

僅供參考,在函數外計算字典對於大批轉換更爲有效。

0

下面是一個base10數字轉換baseK並返回一個完整的解決方案:相比C.

public class Program 
{ 
    public static void Main() 
    { 
     int i = 100; 

     Console.WriteLine("Int:    " + i); 

     // Default base definition. By moving chars around in this string, we can further prevent 
     // users from guessing identifiers. 
     var baseDefinition = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
     //var baseDefinition = "WBUR17GHO8FLZIA059M4TESD2VCNQKXPJ63Y"; // scrambled to minimize guessability 

     // Convert base10 to baseK 
     var newId = ConvertToBaseK(i, baseDefinition); 
     Console.WriteLine(string.Format("To base{0} (short): {1}", baseDefinition.Length, newId)); 

     // Convert baseK to base10 
     var convertedInt2 = ConvertToBase10(newId, baseDefinition); 
     Console.WriteLine(string.Format("Converted back: {0}", convertedInt2)); 
    } 

    public static string ConvertToBaseK(int val, string baseDef) 
    { 
     string result = string.Empty; 
     int targetBase = baseDef.Length; 

     do 
     { 
      result = baseDef[val % targetBase] + result; 
      val = val/targetBase; 
     } 
     while (val > 0); 

     return result; 
    } 

    public static int ConvertToBase10(string str, string baseDef) 
    { 
     double result = 0; 
     for (int idx = 0; idx < str.Length; idx++) 
     { 
      var idxOfChar = baseDef.IndexOf(str[idx]); 
      result += idxOfChar * System.Math.Pow(baseDef.Length, (str.Length-1) - idx); 
     } 

     return (int)result; 
    } 
} 
+0

@ ashes999足夠公平..鏈接刪除,並用代碼替換回答。 – tbehunin 2016-02-16 22:27:50

相關問題