Back home

الفنون رقم 019

الفنون رقم 019

ARTS هو نشاط بدأه 由左耳朵耗子--陈皓: قم بإجراء سؤال واحد على الأقل عن خوارزمية leetcode كل أسبوع، واقرأ مقالًا تقنيًا واحدًا على الأقل باللغة الإنجليزية وعلق عليه، وتعلم مهارة فنية واحدة على الأقل، وشارك المقالة مع الآراء والأفكار. (أي أن الخوارزمية والمراجعة والنصائح والمشاركة يشار إليها باسم ARTS) وتستمر لمدة عام واحد على الأقل.

الفنون 019

هذه المادة 19

سؤال خوارزمية الخوارزمية

804. كلمات شفرة مورس الفريدة

الصعوبة ** السهل **

تحدد شفرة مورس الدولية ترميزًا قياسيًا حيث يتم تعيين كل حرف إلى سلسلة من النقاط والشرطات، كما يلي: "a" يعين ".-"، "b" يعين "-..."، "c" يعين "-.-."، وهكذا.

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

[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]

الآن، في ضوء قائمة الكلمات، يمكن كتابة كل كلمة كسلسلة من رمز مورس لكل حرف. على سبيل المثال، يمكن كتابة “cba” كـ “-.-…–…”، (وهي السلسلة “-.-.” + “-…” + “.-”). سوف نسمي هذا التسلسل، تحويل الكلمة.

قم بإرجاع عدد التحويلات المختلفة بين جميع الكلمات لدينا.



Example:
Input: words = ["gin", "zen", "gig", "msg"]
Output: 2
Explanation: 
The transformation of each word is:
"gin" -> "--...-."
"zen" -> "--...-."
"gig" -> "--...--."
"msg" -> "--...--."

There are 2 different transformations, "--...-." and "--...--.".

ملاحظة:

  • سيكون طول الكلمات 100 كلمة على الأكثر.
  • كل كلمة [i] سيكون لها طول في النطاق [1، 12].
  • الكلمات [i] ستتكون من أحرف صغيرة فقط.

الحل

اللغة: ج

الطريقة الأولى: هذه هي الطريقة الأسهل للتفكير فيها، قم بتحويل الكلمات مباشرة إلى Morma، ثم قارن بين التكرارات وأزلها

int uniqueMorseRepresentations(char** words, int wordsSize) {
    char *morse[26] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
    
    
    //convert words to morse
    char **chatToMorse = (char **)malloc(sizeof(char*) * wordsSize);
    int index = 0;
    while (index < wordsSize) {
        char *word = words[index];
        char *charMorse = NULL;
        for (int j = 0; j <  strlen(word); j++) {
            char charter = word[j];
            char *newmorse = morse[charter - 'a'];
            
            if (charMorse == NULL) {
                char *result = malloc(strlen(newmorse)+1);
                memset(result, '\0', strlen(newmorse)+1);
                strcpy(result, newmorse);
                charMorse = result;
            }
            else{
                char *result = malloc(strlen(charMorse)+strlen(newmorse)+1);//+1 for the zero-terminator
                memset(result, '\0', strlen(charMorse)+strlen(newmorse)+1);
                strcpy(result, charMorse);
                strcat(result, newmorse);
                free(charMorse);
                charMorse = result;
            }
        }
        chatToMorse[index] = charMorse;
        ++index;
    }
    
    int falg = 0;
    for (int m =0; m < wordsSize; m++) {
        char *  ms = chatToMorse[m];
        if(ms == NULL){
            continue;
        }
        for(int n = m+1; n <wordsSize;n++ ){
            char *  ns = chatToMorse[n];
            if (ns != NULL)  {
                int res = strcmp(ms,ns);
                if (res ==0) {
                    chatToMorse[n] = NULL;
                    falg++;
                }
            }
        }
    }
    return wordsSize -falg;
}

الطريقة الثانية: فكرة هذه الطريقة هي نفس فكرتي ولكنها أسرع من فكرتي. يجب أن يكون ذلك لأنه لا يخصص الذاكرة بشكل حيوي. شيء آخر هو أن الحساب النهائي لإلغاء البيانات المكررة يختلف عن حسابي. لكن هذا الكود أفضل من الكود الخاص بي لأنه يحتوي على وظائف مختلفة في الكود وله تفكير موجه للكائنات.


char *transMorse(const char alphabet){
    char *morseCode[] = { ".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.." };
    return morseCode[alphabet-'a'];
}

void transMorseString(char *word, char *morseString){
    char *morseTempt;
    while(*word){
        morseTempt = transMorse(*word);
        word++;
        while(*morseTempt){
            *morseString = *morseTempt;
            morseString++;
            morseTempt++;
        }
    }
    return;
}

int uniqueMorseRepresentations(char** words, int wordsSize) {
    char morseString[100][50] = {""};
    
    for(int i = 0 ; i<wordsSize ; ++i){
        transMorseString(words[i], morseString[i]);
    }
    
    //上面的方法h都好理解,就是把字符串转为Morse码
    //下面的这个去重计算 感觉不好理解
    for(int i = 0 ; i<wordsSize ; ++i){
        for(int j = i+1 ; j<wordsSize ; ++j){
            while(wordsSize>1 && j<wordsSize && !strcmp(morseString[i], morseString[j])){
                strcpy(morseString[j], morseString[wordsSize-1]);
                --wordsSize;
            }
        }
    }
    return wordsSize;
}


الطريقة الثالثة: مزايا هذه الطريقة:

  1. يعد استخدام الطريقة ثنائية الأبعاد أكثر ملاءمة عند تحويل سلسلة إلى رمز معنوي.
  2. يتم استخدام مفهوم المجموعة عند إزالة التكرارات

وخاصة النقطة 2، فكرة التجمع، أليس هذا هو الوضع الذي يكون فيه التجمع مفيدًا، لكنني لم أتوقع ذلك.


int addToSet(char** set, int setCount, char* buf);

int uniqueMorseRepresentations(char** words, int wordsSize) {
    char* morse[26] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
    char* set[100];
    int setCount = 0;
    //1. 字符串转摩尔码的时候用了二维方法的时候 比较方便
    //2. 去重的时候用到了集合(set)的概念
    int i = 0;
    for(i = 0; i < wordsSize; i++) {
        char* buf = malloc(sizeof(char) * 60);
        buf[0] = '\0';
        int j = 0;
        for(j = 0; j < strlen(words[i]); j++) {
            char* cat = strcat(buf, morse[words[i][j] - 97]);
            
            printf("add: %c %s, all is: %s", words[i][j], morse[words[i][j] - 97], cat);
        }
        setCount = addToSet(set, setCount, buf);
        printf("\n");
    }
    
    for(i = 0; i < setCount; i++) {
        free(set[i]);
    }
    
    return setCount;
}

int addToSet(char** set, int setCount, char* buf) {
    int i = 0;
    for(i = 0; i < setCount; i++) {
        printf("compare: %s %s", set[i], buf);
        if(strcmp(set[i], buf) == 0) {
            return setCount;
        }
    }
    
    set[i] = buf;
    return ++i;
}



الطريقة الرابعة: فكرة هذه الطريقة جيدة جدًا أيضًا. فكر في Morma كثنائي 0 و1، . يمثل 0، ويمثل 1 -. راجع تعليقات الكود للحصول على التفاصيل


typedef struct {
    char len;
    char val;
} morseCode;

morseCode codeTable[] = {
    {2, 2}, /* a .-   10*/
    {4, 7}, /* b -... 0111*/
    {4, 5}, /* c -.-. 0101 */
    {3, 3},
    {1, 1},
    {4,13},
    {3, 1},
    {4,15},
    {2, 3},
    {4, 8},
    {3, 2},
    {4,11},
    {2, 0},
    {2, 1},
    {3, 0},
    {4, 9},
    {4, 2},
    {3, 5},
    {3, 7},
    {1, 0},
    {3, 6},
    {4,14},
    {3, 4},
    {4, 6},
    {4, 4},
    {4, 3}
};

typedef struct{
    int len;
    int val;
}morseString;

morseString getmorseString(char* s) {
    morseString str;
    str.len = 0;
    str.val = 0;

    char *p = s;
    while(*p != '\0')
    {
        char c = *p;
        if (c < 'a' || c > 'z'){
            printf("Invalid input *p = %c\n", c);
            p++;
            continue;
        }

        morseCode code = codeTable[c - 'a'];
        str.len += code.len;//记录单词转为摩尔码,也就是二进制之后的位数,当数据很长时有用,如果数据较短,比如没有超过64位或32位。但是超过之后这个就有用了
        str.val = (str.val << (code.len)) + code.val;//把str.val看成二进制数据 就容易理解了
        p++;
    }

    return str;
}

int uniqueMorseRepresentations(char** words, int wordsSize) {
    int result = -1;
    morseString stack[100];

    for(int i = 0; i < wordsSize; i++)
    {
        morseString str = getmorseString(words[i]);
        bool foundone = false;
        for (int j = 0; j <= result; j++)
        {
            // check one by one if str in stack
            // zstack[j].len == str.len 这个判断当摩尔码的二进制长度超过机器的最大字长时才有用。
            // 如果没有超过最大字长,二进制表示相等(stack[j].val == str.val),二进制的长度必然相等
            if (stack[j].len == str.len && stack[j].val == str.val) {
                foundone = true;
                break;
            }
        }

        if (!foundone)
        {
            stack[++result] = str;
        }
    }

    return result + 1;
}


الطريقة الخامسة: طريقة أكثر إرضاءً، باستخدام مصفوفة ثنائية الأبعاد، وهي أبسط من طريقة كتابتي.


int uniqueMorseRepresentations(char** words, int wordsSize) {
    char transBuffer[50] = {0};
    char transCode[100][50] = {0}; //Store the translation code
    char* morseCode[] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."}; // 'a' ~ 'z' Morse Code Table
    
    int j, k;
    int existFlag = 0;
    int transCodeNum = 0;               //Different translation code numbers
    for(int i=0; i < wordsSize; i++)
    {
        j = 0;
        k = 0;
        existFlag = 0;                                      //Reset the flag
        memset(transBuffer, 0, sizeof(transBuffer));        //Reset the buffer
        while(words[i][j] != '\0')
        {
            k = words[i][j] - 'a';                          //get the number of letters
            strncat(transBuffer, morseCode[k], sizeof(morseCode[k]));   //translate the letter by morseCode
            j++;
        }
        
        
        for(int z = 0; z < transCodeNum && !existFlag; z++)     //Confirm transCode has already store same code
            if(strncmp(transCode[z], transBuffer, sizeof(transBuffer)) == 0)
                existFlag = 1;
        
        if(!existFlag)                                          //if the code isn't exist, store it
            strncpy(transCode[transCodeNum++], transBuffer, sizeof(transBuffer));
        
    }
    
    return transCodeNum;
}

مراجعة

تتناول هذه المقالة: كيف تصبح مطور برامج أفضل التحدث عن أشياء أخرى غير مهارات التطوير: 1 فهم عملية التطوير بأكملها. من المستحسن ألا يركز المطورون على البرمجة فحسب، بل يجب أيضًا أن يكونوا على دراية بعملية التطوير بأكملها، وعملية التحويل من الأفكار الغامضة إلى الحلول المصممة بعناية، والاختبار والنشر والمراقبة والتحليل والتحسين بعد اكتمال تطوير البرامج. يتيح ذلك للجميع فهم بعضهم البعض وتقليل حواجز الاتصال الناتجة عن الفهم المتبادل لعمل الآخرين. 2 فهم احتياجات العملاء والتواصل مع العملاء وتحقيق الثقة المتبادلة وتقديم الملاحظات في الوقت المناسب عن التقدم والنتائج للعملاء. 3 ـ اختيار حلول أو أدوات مختلفة لوظائف مختلفة، ولا يستطيع استخدام المهارات والخبرات الموجودة في كل شيء. 4. الوقوف على أكتاف العمالقة وإتقان استخدام أدوات الطرف الثالث بدلاً من تطويرها من الصفر في كل مرة. 5. لتعلم المبادئ الأساسية للمعرفة، لا يمكنك متابعة المعرفة الجديدة بشكل أعمى. يجب أن تفهم المبادئ الكامنة وراء المعرفة.

للترجمة انظر: https://dandan2009.github.io/2018/12/18/how-to-become-a-better-software-developer/ انظر النص الأصلي: https://medium.com/devtrailsio/how-to-become-a-better-software-developer-dd16072c974e

نصائح

في السابق، تم استخدام الأدوات لاختبار وقت بدء تشغيل التطبيق. يمكنه فقط تسجيل أحداث التنفيذ لطريقة معينة. يمكنك الآن استخدام Signposts لتسجيل وقت تشغيل كل سطر من كود التطبيق: راجع مؤتمر WWDC2018 قياس الأداء باستخدام التسجيل: https://developer.apple.com/videos/play/wwdc2018/405/

هنا ترجمة يمكنك قراءتها: https://blog.csdn.net/tugele/article/details/81252603

يعتمد المثال المذكور أعلاه على Swift، ويمكن استخدام إصدار لغة C في Objective-C:

  os_log_t log = os_log_create("com.example.your-app",  "RefreshOperations");
  os_signpost_id_t log_t = os_signpost_id_generate(log);
  
   os_signpost_interval_begin(log, log_t, "Fetch Asset");
   你的代码
   os_signpost_interval_end(log, log_t, "Fetch Asset");
   
   os_signpost_interval_begin(log, log_t, "Fetch Asset1");
   你的代码
   os_signpost_interval_end(log, log_t, "Fetch Asset1");

شارك

عرض أسعار التوظيف: https://readhub.cn/jobs

الباحث العلمي من Google، ويكيبيديا، ترجمة Google، ويب Gmail، صور Google، مستندات Google، Google Keep، Google Earth، كتب Google، Chrome Sync، Pixiv، مجتمع Steam، إصدارات GitHub، Pinterest، Vimeo، Yandex، Tumbl يوتيوب، تويتر، فيسبوك، جوجل بلس، جوجل بلاي، جوجل درايف، بلوجر، بعض المواقع الإخبارية، إنستجرام

تعلم اللغة الإنجليزية: https://learnamericanenglishonline.com/Red Level/R1 Do.html

فك تشفير Runloop: http://mrpeak.cn/blog/ios-runloop/

مشغل Mac مفتوح المصدر: 15000 نجمة، IINA هو مشغل الفيديو الحديث لنظام التشغيل macOS. https://github.com/lhc70000/iina

مثال لكسب المال من خلال البرامج الصغيرة المطورة: https://www.v2ex.com/t/515777

يمكن الوصول إلى جوجل: https://sss.cnsdhh.com/

موقع للبحث عن الألوان: https://picular.co/,搜索出来的颜色是一个色系的,不是单一的一种颜色