كيف يمكنني تحويل رقم إلى قاعدة مخصصة 2 Charch والعودة؟ (AKA: كيفية القيام بضغط خاصية جدول Azure)

StackOverflow https://stackoverflow.com/questions/3740865

سؤال

على غرار كيف يمكن للمرء أن يحسب من 0 إلى F في Hex ، لدي مجموعة من الأرقام والرسائل التي أريد "العد" من ... وعندما وصلت إلى القيمة القصوى ، أريد أن أبدأ من جديد في "TENS" " عمودي.

أحتاج إلى هذا لزيادة كفاءة التخزين في طاولة Azure ، وللحفاظ على quictkeys ripainy (حتى أتمكن من استخدامها في Tinyurl). أولاً ، ضع في اعتبارك أنه لا يُسمح إلا بأن هذه الأحرف بمثابة اسم خاصية ، كما هو موثق هنا. في الصفيف أدناه ، يتم وضع كل حرف وفقًا لكيفية حل Azure.

  public static string[] AzureChars = new string[]
   {
        "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"       
   };

هدفي هو استخدام أحرف 2 String/ASCII للعد من السلسلة "00" إلى صغر "ZZ".

ما هي أفضل طريقة للتعامل مع هذا المفهوم باستخدام C#؟
- هل الصفيف هو الكائن الصحيح لاستخدامه؟
- كيف سأربط شخصية معينة (أحرف كبيرة "y") بموقفها في المصفوفة؟

أنا فقط أجرب هذه الفكرة. في البداية ، يبدو أن الفرشاة جيدة ، لكنني لم أر أي شخص يفكر في فعل الأشياء بهذه الطريقة. ماذا تعتقد؟

هل كانت مفيدة؟

المحلول

أنت تسأل حقًا حول تحويل رقم إلى رقم 62 من رقمين. فيما يلي مقتطف عام من التعليمات البرمجية لتحويل رقم إيجابي إلى قاعدة تعسفية:

var n = 1234;
var baseNumber = 62;
var numberOfDigits = 2;
var digits = new Int32[numberOfDigits];
for (var i = 0; i < digits.Length; i += 1) {
  digits[i] = n%baseNumber;
  n /= baseNumber;
}

يجب عليك تعيين الأرقام في أحرف وجدول بحث أو وظيفة صغيرة للقيام بذلك مناسبة.

لمشكلتك المحددة مع الميزة الإضافية المتمثلة في وجود عدد متغير من الأرقام ، سأكتب هذا الرمز:

var n = 123456; 
var digitCount = 3;
var digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var number = String.Empty;
for (var i = 0; i < digitCount; ++i) {
  number = digits[n%digits.Length] + number;
  n /= digits.Length;
}

لاحظ أن هذا الرمز سيتم تحويله 0 داخل 000, 1 داخل 001 وما إلى ذلك ، لكنني أعتقد أن هذا في الواقع ما تريده.

لتحويل مرة أخرى ، يمكنك استخدام هذا الرمز:

var n = 0;
for (var i = 0; i < number.Length; ++i)
  n = n*digits.Length + digits.IndexOf(number[i]);

ال String.IndexOf() ليست الطريقة الأكثر فعالية للقيام بالتحويل ولكن في معظم الحالات يجب أن تكون على ما يرام.

لاحظ أنه إذا كان رقمك الأصلي أكبر من أكبر رقم يمكن تخزينه في رقم 62 قاعدتك ، فسيؤدي ذلك التحويل إلى رقم مختلف. لمدة 3 أرقام في القاعدة 62 ، يكون هذا صحيحًا إذا كان الرقم الأصلي أكبر من أو يساوي zzz = 62^3 - 1 = 238327.

نصائح أخرى

نظرًا لأن عناصر صفيفك كلها أحرف واحدة ، فربما يمكنك إعلانها كمجموعة من الشخصيات:

public static char[] AzureChars = new char[]
{
    '0', '1', '2', '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'       
};

الآن يمكنك بسهولة كتابة وظيفة تقوم بإرجاع المجموعة الكاملة من الجميع ن-سلاسل character لأي طول سلسلة مطلوب ن. روايتي متكررة. إذا وجدت أنه بطيء جدًا بالنسبة للسلاسل الطويلة ، فربما يمكنك تحسينها:

public static IEnumerable<string> AzureStrings(int desiredLength)
{
    if (desiredLength == 0)
        return new[] { "" };
    return AzureChars.SelectMany(ch => AzureStrings(desiredLength - 1)
                                       .Select(str => ch + str));
}

الآن يمكننا توليد أي جزء من التسلسل باستخدام Skip و Take:

// Prints “5v, 5w, 5x, 5y, 5z, 60, 61, 62, 64, 65”
Console.WriteLine(string.Join(", ", AzureStrings(2).Skip(300).Take(10)));
// Prints “3721”
Console.WriteLine(AzureStrings(2).Count());

على الرغم من حقيقة أن هذا يحسب أول 300 عنصر قبل إخراج أي شيء ، إلا أنه سريع بما يكفي بالنسبة لي. حتى هذا الحساب المجنون هنا يستغرق أقل من ثانية:

// Prints “5PkS, 5PkT, 5PkU, 5PkV, 5PkW, 5PkX, 5PkY, 5PkZ, 5Pka, 5Pkb”
Console.WriteLine(string.Join(", ", AzureStrings(4).Skip(1000000).Take(10)));

استخدم المعامل لذلك (واحصل على الباقي)

        int i = AzureChars.Length;
        int index = 62 //character to lookup;
        string a = AzureChars[index % i];

احصل على فهرس char:

        int index = Array.IndexOf(AzureChars, "Y");

مثل:

        string text = "YY";
        int index1 = Array.IndexOf(AzureChars, text[1].ToString());
        int index2 = Array.IndexOf(AzureChars, text[0].ToString());

ربما يجب عليك استخدام chararray (char []) بدلاً من ذلك ، أو مجرد سلسلة طويلة مثل:

 static string AzureChars= "012456789.....qrstuvwxyz";

جميعًا معًا لتوضيح ذلك:

    static void Main(string[] args)
    {
        char[] b = AzureCharConverter.ToCharArray(522);
        int i = AzureCharConverter.ToInteger(b);
    }


    public static class AzureCharConverter
    {
         private static readonly string _azureChars
         = "012456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

         public static int ToInteger(string chars)
         {
                 int l = _azureChars.IndexOf(chars[0]);
                 int r = _azureChars.IndexOf(chars[1]);
                 return (l * _azureChars.Length) + r;
         }


         public static char[] ToCharArray(int value)
         {
                  char l = _azureChars[value / _azureChars.Length];
                  char r = _azureChars[value % _azureChars.Length];
                  return new char[] { l, r };
         }
    }

إن شريطة أن يكون alpha مدخلات دائمًا رقمين والنتيجة تكون دائمًا أقل من 3720

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top