2022年11月13日 星期日

密笈?!

咳咳咳...

===比數字===
int comp(const void *a , const void *b)
{
    return (*(int *)a - *(int*)b);
}
 qsort((void *)coins,coinsSize,sizeof(int),comp);

===比字串===
int comp (const void *a , const void *b)
{
    return strcmp((char *)a, (char *)b);
}
qsort(s,len,sizeof(char),comp);

===比數字的二維陣列===
int comp(const void *a, const void *b)  
{  
    int *A= *(int **)a;
    int *B= *(int **)b;
    return A[0]-B[0];
}

qsort((void *)points, pointsSize, sizeof(points[0]), comp);

(另一種?!)
int comp(const void *a, const void *b)
{
    int* p1 = *(int **)a;
    int* p2 = *(int **)b;
    return p1[1]-p2[1];

}
qsort(intervals, intervalsSize, sizeof (int*), comp);

如果數字相減會overflow,就改成比大小後回傳0, 1, -1

int comp(const void *a, const void *b)
{
    int *A= *(int**)a;
    int *B= *(int**)b;
    if (A[1]==B[1])
        return 0;
    else 
        return (A[1] > B[1]) ? (1) : (-1);
}
qsort((void *)points, pointsSize,sizeof (int**), comp);


===malloc===
char* str = malloc (sizeof(char)*(maxLen+2));
int* ret = malloc (sizeof(int)*numsSize);

===calloc===
char *ret = calloc(len, sizeof(char));

數字初始化為零
int *count = calloc (len,sizeof(int)*(len));

===memset & memcpy===
memcpy(dest,source,sizeof(int)*numsSize);
memset(stack, 0, sizeof(char) * (maxLen *maxLen));

(二維)memcpy 如果宣告時是 ** 則 :

輸入為 **grid ,  m x n 大小
int **rotate = calloc (m, sizeof(int *));
for (int i=0;i<m; i++)
    rotate[i]= calloc (n, sizeof(int));
memcpy(rotate, grid, sizeof(int*)*m);
此時sizeof(int) 是4 , sizeof (int*) 跟sizeof(int**) 跟sizeof (grid)都是8
但是此方法有可能有copy到garbage的情況?! 建議還是兩個for 下去複製......QQ
(沒時間debug XD 或是歡迎知道原因的人在下面留言(?))
使用memcmp看了一下,使用memcpy確實是兩組一樣的。反而assign的話會變成兩者不同!
(大驚)
再度推測,因為grid 是傳進來的,因此可能?!(好吧真的沒時間了,這問題先停在這Orz)

若是用[] [] 方式則 (用 2x3舉例)
    int TEST[2][3]={{4,3,2},{4,3,2}};
    int OUT[2][3]={{1,2,3},{1,2,3}};
    memcpy(OUT, TEST, sizeof(int)*(2*3));

===quick sort 例子===
void swap(int *a, int *b)
{
    int tmp;
    tmp = *a;
    *a=*b;
    *b=tmp;
}

void qqsort(int* nums,int low, int right)
{
    int l=low, r=right;
    int mid = (l+r)/2;
    int pivot= nums[mid];
    while (l<=r)
    {
        while (nums[l]< pivot)
            l++;
        while (nums[r]>pivot)
            r--;
        if (l<=r)
        {
            swap(&nums[l],&nums[r]);
            l++;
            r--;
        }
    }
    if (low<r)
        qqsort(nums,low,r);
    if (l<right)    
        qqsort(nums,l,right);
}

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    if (n==0 && m==1)
        return;
    if (n==1 && m==0)
    {
        nums1[0]=nums2[0];
        return;
    }

    for (int i =m;i< m+n;i++)
        nums1[i]=nums2[i-m];
    qqsort(nums1,0,nums1Size-1);

}

=====binary search=====
    
int search(int* nums, int numsSize, int target){
    int left=0,right=numsSize-1;
    int mid=(left+right)/2;
    while (left<=right)
    {
        mid=(left+right)/2;
        if (nums[mid] < target)
            left=mid+1;
        else if (nums[mid]> target)
            right=mid -1;
        else
            return mid;
    }
    return -1;
}

=====新版 malloc & return column=====


int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){

    int count= factorial(numsSize);

    *returnSize = count;

    int **ret = malloc(sizeof(int*)* (count));

    *returnColumnSizes= malloc (sizeof(int)*(count));

    for (int i=0;i<(count);i++)

    {

        ret[i]=malloc(sizeof(int)*numsSize);

        (*returnColumnSizes)[i]= numsSize;

    }

    count=0;

    myPermute(nums, numsSize,&count,0,numsSize-1,ret);

    return ret;    

}


要用到的時候再calloc / malloc 就好了,不用一定要先用for 回圈跑起來初始化

例子: 
int checkSum(struct TreeNode* root, int **ret, int **returnColumnSizes, int *data)
{
    ret[o_idx]=calloc(idx+1, sizeof(int)); //宣告 ret[i][j]的 j的部分
    o_idx = checkSum(root->left, target, idx+1,o_idx, ret, returnColumnSizes,data);
}

int** pathSum(struct TreeNode* root, int targetSum, int* returnSize, int** returnColumnSizes) {
    int** ret = calloc (5000, sizeof(int*)); //宣告全部的size
    *returnSize = checkSum(root, returnColumnSizes, data);
    return ret;
}

=====又再次複習傳**去function的時候怎麼用=====
void backtracking(int *curr, int currIdx ,int **ret, int* candidates, 
                int candidatesSize,int canIdx ,int target, int* returnSize, 
                int** returnColumnSizes)
{
        ret[(*returnSize)]= calloc (currIdx, sizeof(int));
        (*returnColumnSizes)[(*returnSize)] = currIdx;
#if 1  
        for (int i=0;i<currIdx;i++)
            ret[(*returnSize)][i]= curr[i];
#else
        memcpy(ret[(*returnSize)], curr, currIdx * sizeof(int));
#endif
        (*returnSize)++;
}


int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
    int **ret = calloc (MAXLEN, sizeof(int*));
    (*returnColumnSizes)= calloc (MAXLEN, sizeof(int));
    (*returnSize) =0;
    int *curr = calloc (MAXLEN, sizeof(int));
    backtracking(curr, 0 ,ret, candidates, candidatesSize, 0,
             target, returnSize, returnColumnSizes);
    return ret;
}

=====C的hash table 怎麼用=====
(好像要include東西,但看起來leetcode裡面有包 XD)


struct hash_struct{

    int id;

    int value;

    UT_hash_handle hh;

};


struct hash_struct *hash=NULL; //整個hash table

struct hash_struct *tmp=NULL;  //要新建的時候拿來當做tmp pointer


//(建table)


HASH_FIND_INT( hash, &nums[i], tmp );  //先看這個element 在不在裡面,用id找

if (tmp == NULL)

{

    tmp=malloc (sizeof (struct hash_struct)*1);

    tmp->id= nums[i];

    tmp->value=i;

    HASH_ADD_INT(hash, id ,tmp);  //不在的話加進去。第二個參數"id"是欄位的名字"id",就是這樣寫XD

}


=====宣告一個function pointer=====
回傳值是int , 參數是一個int
int (*a)(int);

========================
linked list 的head 宣告法 (先用一個node list pointer , 再指向它?!)
========================
(先建了一個, 不管它是不是head 會有東西?!)
struct ListNode *listNode = (struct ListNode *)malloc(sizeof(struct ListNode));
struct ListNode *head = listNode;
listNode->next = (struct ListNode *)malloc(sizeof(struct ListNode));
listNode = listNode->next;
(離開回圈後)
listNode->next = NULL;
return head;


===另一種寫法: 
struct ListNode* insertNode(int val)
{
    struct ListNode *ptr = calloc (1, sizeof(struct ListNode));
    ptr->val = val;
    ptr->next = NULL;
    return ptr;
}

先建一個node , 把它的address 指給之後要移動的ptr
struct ListNode head;
head.next = NULL;
struct ListNode *tail = &head;
tail->next = insertNode(tail, add);
tail = tail->next;
(離開回圈後)
return head.next; (回傳的是head的next !!! 因為head 原本是dummy 指向head的前一個!)

===比較接近我思維的寫法:

struct ListNode *head = NULL;
struct ListNode *tail = NULL;

if (head == NULL)
{
head = insertNode(add);
        tail = head;        // malloc 完才能把tail 指去head
}
else
{
tail->next = insertNode(add);
        tail = tail->next;
}
return head;

===一個 array pointer 跟它們的index & return 要怎麼宣告&呼叫要怎麼用的例子

void bfs(struct TreeNode* root,int **ret,int *column, int level)
{
    if (root== NULL)
        return;
    ret[level][column[level]] = root->val;
    (column[level])++;
    bfs(root->left,ret, column, level+1);
    bfs(root->right,ret, column, level+1);
}

int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
    int depth= dfs(root,0);
    int **ret = calloc (depth, sizeof(int*));
    (*returnColumnSizes) = calloc (depth, sizeof(int));
    for (int i=0; i<depth; i++)
        ret[i] = calloc (1024, sizeof(int));

    bfs(root,ret,(*returnColumnSizes),0);
    *returnSize = depth;
    return ret;    
}

沒有留言:

張貼留言