20160219.CCPP體系詳解(0029天)

尹成發表於2016-03-15

程式片段(01):ReplaceAll.c
內容概要:ReplaceAll

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//01.(刪除+替換)所有指定字串
//  (雙索引+雙指標)-->(刪除+替換)原理
//  注:增加(擴充)+刪除(壓縮)+修改(壓縮|不變|擴充)+查詢(不變)
void replaceAll(char ** ppSrcStr, char * pOldStr, char * pNewStr)
{
    char * pSrcStr = *ppSrcStr;//常量指標-->變數指標(同一本體)-->跨函式間接修改常量指標
    int srcStrLen = strlen(pSrcStr);
    int oldStrLen = strlen(pOldStr);
    int newStrLen = strlen(pNewStr);
    char * p1 = pSrcStr;
    char * p2 = pSrcStr;
    if (oldStrLen == newStrLen)
    {
        while (*p1 = *p2)
        {
            int find = 1;
            for (int i = 0; i < oldStrLen; ++i)
            {
                if ('\0' == *(p2 + i) || *(p2 + i) != *(pOldStr + i))
                {
                    find = 0;
                    break;
                }
            }
            if (!find)
            {
                ++p2;
                ++p1;
            }
            else
            {
                for (int i = 0; i < newStrLen; ++i)
                {
                    *(p2 + i) = *(pNewStr + i);
                }
            }
        }
    }
    else if (oldStrLen < newStrLen)
    {
        while (*p1 = *p2)
        {
            int find = 1;
            for (int i = 0; i < oldStrLen; ++i)
            {
                if ('\0' == *(p2 + i) || *(p2 + i) != *(pOldStr + i))
                {
                    find = 0;
                    break;
                }
            }
            if (!find)
            {
                ++p2;
                ++p1;
            }
            else
            {
                int m = p2 - pSrcStr;
                int n = p1 - pSrcStr;
                pSrcStr = *ppSrcStr = (char *)_recalloc(*ppSrcStr, srcStrLen + newStrLen - oldStrLen + 1, sizeof(char));
                p2 = pSrcStr + m;
                p1 = pSrcStr + n;
                int moveLen = newStrLen - oldStrLen;
                for (char * p = p2 + strlen(p2); p >= p2; --p)
                {
                    *(p + moveLen) = *p;
                }
                for (int i = 0; i < newStrLen; ++i)
                {
                    *(p2 + i) = *(pNewStr + i);
                }
            }
        }
    }
    else
    {
        while (*p1 = *p2)
        {
            int find = 1;
            for (int i = 0; i < oldStrLen; ++i)
            {
                if ('\0' == *(p2 + i) || *(p2 + i) != *(pOldStr + i))
                {
                    find = 0;
                    break;
                }
            }
            if (!find)
            { 
                ++p2;
                ++p1;
            }
            else
            {
                for (int i = 0; i < newStrLen; ++i)
                {//賦值有效字串
                    *(p2 + oldStrLen - newStrLen + i) = *(pNewStr + i);
                }
                p2 += oldStrLen - newStrLen;//跳過無效字串
            }
        }
    }
}

int main01(void)
{
    int srcStrLen = strlen("12345543211234554321");
    char * pStr = (char *)malloc(srcStrLen + 1);
    strcpy(pStr, "12345543211234554321");
    printf("%s \n", pStr);
    //replaceAll(&pStr, "12345", "ABCDE");
    //replaceAll(&pStr, "123", "ABCDE");
    replaceAll(&pStr, "12345", "ABC");                                                  
    printf("%s \n", pStr);

    system("pause");
}

程式片段(02):獲取最長數字串.c
內容概要:尋找母串當中最長的數字子串

#include <stdio.h>
#include <stdlib.h>

int main01(void)
{
    char * pInputStr = "abc12345hij1234321jkl1237ol";
    char * pMaxNumStr = NULL;
    int maxNumLen = 0;
    char * pChr = pInputStr;//指向普通字元的指標
    while (*pChr)
    {
        while (!('0' <= *pChr && *pChr <= '9'))
        {
            ++pChr;
        }
        char * pNum = pChr;//指向數字字元的指標
        while ('0' <= *pChr && *pChr <= '9')
        {
            ++pChr;
        }
        if (pChr - pNum > maxNumLen)
        {
            maxNumLen = pChr - pNum;
            pMaxNumStr = pNum;
        }
    }
    printf("%d \n", maxNumLen);
    for (int i = 0; i < maxNumLen; ++i)
    {
        putchar(*(pMaxNumStr + i));
    }

    system("pause");
}

程式片段(03):陣列.c
內容概要:遞迴的高階形式判定陣列是否遞增

#include <stdio.h>
#include <stdlib.h>

int loopJudge(int * pArr, int num)
{
    for (int i = 0; i < num - 1; ++i)
    {
        if (*(pArr + i) > *(pArr + i + 1))
        {
            return 0;
        }
    }
    return 1;
}

//01.遞迴的高階形式:
//  通過邏輯運算子建立遞迴關係
int recurJudge(int * pArr, int num)
{
    if (1 == num)//保證判定式成立
        return *(pArr + 0) < *(pArr + 1);
    //形成整體表示式
    return *(pArr + num - 2) < *(pArr + num - 1) && recurJudge(pArr, num - 1);
}

int main01(void)
{
    int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    //printf("%d \n", loopJudge(arr, 10));
    printf("%d \n", recurJudge(arr, 10));

    system("pause");
}

程式片段(04):01.陣列最大值.c+02.冒泡求最大值.c
內容概要:取陣列最大值迴圈遞迴

///01.陣列最大值.c
#include <stdio.h>
#include <stdlib.h>

int maxNumByLoop(int * pArr, int num)
{//打擂演算法
    int maxNum = *(pArr + 0);
    for (int i = 1; i < num; ++i)
        if (maxNum < *(pArr + i))
            maxNum = *(pArr + i);
    return maxNum;
}

int maxNumByRecur(int * pArr, int num, int maxValue)
{
    if (0 == num)//表示式恆成立
    {
        if (maxValue < *(pArr + 0))
        {
            maxValue = *(pArr + 0);
        }
        return maxValue;
    }
    if (maxValue < *(pArr + num - 1))
    {//直接陣列個數
        maxValue = *(pArr + num - 1);
    }
    maxNumByRecur(pArr, num - 1, maxValue);
}

int main02(void)
{
    int arr[10] = { 1, 4, 5, 9, 18, 13, 2, 0, 12, 8 };
    printf("maxValue = %d \n", maxNumByLoop(arr, 10));
    printf("maxValue = %d \n", maxNumByRecur(arr, 10, 0));

    system("pause");
}
///02.冒泡求最大值.c
#include <stdio.h>
#include <stdlib.h>

static int maxNumByRecur(int * pArr, int num)
{//遞迴演算法
    if (1 == num)
    {
        if (*(pArr + 0) < *(pArr + 1))
        {
            *(pArr + 0) = *(pArr + 0) ^ *(pArr + 1);
            *(pArr + 1) = *(pArr + 0) ^ *(pArr + 1);
            *(pArr + 0) = *(pArr + 0) ^ *(pArr + 1);
        }
        return *(pArr + 0);
    }
    if (*(pArr + num - 2) < *(pArr + num - 1))
    {
        *(pArr + num - 2) = *(pArr + num - 2) ^ *(pArr + num - 1);
        *(pArr + num - 1) = *(pArr + num - 2) ^ *(pArr + num - 1);
        *(pArr + num - 2) = *(pArr + num - 2) ^ *(pArr + num - 1);
    }
    maxNumByRecur(pArr, num - 1);
}

int main02(void)
{
    int arr[10] = { 1, 2, 3, 4, 15, 18, 4, 3, 2, 1 };
    //for (int i = 0; i < 10 - 1; ++i)
    //{//冒泡演算法
    //  if (*(arr + i) > *(arr + i + 1))
    //  {
    //      *(arr + i) = *(arr + i) ^ *(arr + i + 1);
    //      *(arr + i + 1) = *(arr + i) ^ *(arr + i + 1);
    //      *(arr + i) = *(arr + i) ^ *(arr + i + 1);
    //  }
    //}
    //printf("maxNum = %d \n", *(arr + 10 - 1));
    printf("maxNum = %d \n", maxNumByRecur(arr, 10));

    system("pause");
}

程式片段(05):01.大數乘法.c+02.大數乘法遞迴.c
內容概要:大數乘法

///01.大數乘法.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//01.大數乘法原理解析:
//                  1   2   3
//                  4   5   6
//--------------------
//                  6    12 18
//              5   10   15
//          4   8   12
//          4   13  28    27 18
//          5   6    0    8     8
//注:圖形化方式進行解析
void largeNumMul(char * pMultiplicand, char * pMultiplicater, char * pResult)
{
    int candLen = strlen(pMultiplicand);
    int caterLen = strlen(pMultiplicater);

    int places = 0;
    for (int j = caterLen - 1, n = 0; j >= 0; --j, ++n)
    {
        if (0 == *(pMultiplicater + j))
        {
            continue;
        }
        int r1 = 0, r2 = 0;
        char * pTmpStr = (char *)calloc(2048, sizeof(char));
        int m = 0;
        for (int i = candLen - 1, m = 0; i >= 0; --i, ++m)
        {
            r1 = (*(pMultiplicand + j) - '0') * (*(pMultiplicater + i) - '0');
            r2 = *(pTmpStr + m + n) + r1;
            *(pTmpStr + m + n) = r2 % 10;//縱向累加
            *(pTmpStr + m + n + 1) = r2 / 10;//橫向進位
        }
        for (places = 0, r2 = 0; places <= m + n + 1 || r2; ++places)
        {
            r1 = *(pResult + places) + *(pTmpStr + places) + r2;
            *(pResult + places) = r1 % 10;//縱向保留
            r2 = r1 / 10;//橫向進位
        }
    }
    for (int k = places - 1; k >= 0; --k)
    {
        if (*(pResult + k))
        {
            for (int l = 0; l <= k / 2; ++l)
            {
                char tmpChr = *(pResult + l);
                *(pResult + l) = *(pResult + k - l);
                *(pResult + k - l) = tmpChr;
            }                                               
            return;
        }
    }
    *(pResult + 0) = '0';
    return;
}

int main01(void)
{
    char multiplicand[1024] = { 0 };
    char multiplicater[1024] = { 0 };
    char result[2048] = { 0 };
    scanf("%s%s", multiplicand, multiplicater);
    largeNumMul(multiplicand, multiplicater, result);
    printf("%s * %s = %s \n", multiplicand, multiplicater, result);

    system("pause");
}
///02.大數乘法遞迴.c
#define _CRT_SECURE_NO_WARNINGS
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100

char str1[MAX_SIZE], str2[MAX_SIZE], str3[MAX_SIZE * 2];

void Init()
{
    for (int i = 0; i < MAX_SIZE * 2; i++)
        str3[i] = '0';
}

void CalcJ(int n, int m, int inc)
{
    if (m >= 0)
    {
        int tmp = (str2[n] - '0') * (str1[m] - '0') + inc + str3[m + n + 1] - '0';
        str3[m + n + 1] = tmp % 10 + '0';
        inc = tmp / 10;
        CalcJ(n, m - 1, inc);
    }
    else if (n >= 0)
    {
        if (inc > 0)
        {
            int tmp = str3[m + n + 1] - '0' + inc;
            str3[m + n + 1] = tmp % 10 + '0';
            inc = tmp / 10;
            CalcJ(n - 1, m, inc);
        }
    }
}

void Work(int n, int m)
{
    if (n == -1)
    {
        return;
    }
    else
    {
        CalcJ(n, m, 0);
        Work(n - 1, m);
    }
}

void Print()
{
    for (int i = 0; i < strlen(str3); i++)
    if (str3[i] != '\0')
        printf("%d", str3[i] - '0');
    printf("\n");
}

int main1()
{
    scanf("%s%s", str1, str2);
    Init();
    Work(strlen(str2) - 1, strlen(str1) - 1);
    Print();
    system("pause");
    return EXIT_SUCCESS;
}

程式片段(06):C99新語法.c
內容概要:C99新語法

#include <stdio.h>
#include <stdlib.h>

//01.C99新語法之陣列的靜態初始化方式:
//  1.根據指定索引實現精確初始化
//  2.其中最大的那個索引代表著最後一個陣列元素的位置
//  3.該初始化方式屬於棧記憶體的靜態初始化方式
//  4.未能初始化到的元素被預設初始化為0
int main01(void)
{
    int arr[] = { [0] = 1,[1] = 2,[2] = 3,[15] = 10 };
    printf("sizeof(arr) = %d \n", sizeof(arr));
    for (int i = 0; i < sizeof(arr) / sizeof(*(arr + 0)); ++i)
    {
        printf("%d \n", *(arr + i));
    }

    system("pause");
}

//02.C99新語法之靜態指定初始化注意事項:
//  1.採用變數指標進行儲存陣列棧記憶體首地址的時候
//      需要明確靜態初始化的解析型別
//  2.嚴格區分常量指標還是變數指標
//  注:free();函式只能指定回收堆記憶體空間
void testStaticArr()
{   
    int * pArr = (int[]) { [1] = 3, [5] = 2 };
    printf("pArr = %p \n", pArr);
    //free(pArr);//free();函式不能回收棧記憶體
    for (int i = 0; i < 6; ++i)
    {
        printf("%d \n", *(pArr + i));
    }
}

int main02(void)
{
    testStaticArr();

    system("pause");
}

//03.C99新語法之結構體變數的指定初始化方式:
//  1.結構體變數的指定初始化方式
//  2.沒有被指定初始化的內容會被按照變數記憶體塊兒
//      的特點清為0
//注:結構體和陣列的普通變數都可以直接採用指定初始化方式
//      進行初始化,無需明確解析型別(指標方式需要)
//04.C99新語法之布林型別的變數:
//  用於儲存邏輯值
struct MyStruct
{
    int num;
    float fl;
    double db;
    _Bool b;
} myStruct = { .num = 10,.fl = 10.9,.db = 19.8,.b = 0 };

//05.有關陣列維度的省略特點:
//  所有陣列,都可以省略其最高維度數(括號維度保留),用於表明該陣列的型別
//  如果是指向陣列的指標,就需要在省略最高維度之後的方括號前面新增(*pArr)
//  注:指向陣列的指標(簡稱陣列指標)-->這是一種標準陣列的宣告方式
int main03(void)
{
    printf("%d, %f, %lf, %d \n", myStruct.num, myStruct.fl, myStruct.db, myStruct.b);
    getchar();
    //指向結構體的指標-->變數指標-->需要明確解析方式-->可以靜態初始化-->可以指定初始化
    struct MyStruct * pMyStruct = (struct MyStruct[]) { [0] = { .num = 10 ,.fl = 10.9 ,.db = 19.8,.b = 0 } ,
        [1] = { .num = 10 }
    };

    system("pause");
}

#define MYPRINT(...) printf(__VA_ARGS__);

//06.C99新語法之帶參巨集的定義方式:
//  1.帶參巨集的定義格式:
//      #define 帶參巨集名(...) 表示式(__VA_ARGS__)
//  2.解釋:
//      (...):表示傳遞進來的可變引數
//      __VA__ARGS:代表可變引數的應用位置
//  注:三個點兒...-->採用-->__VA_ARGS進行整體替換
int main04(void)
{
    MYPRINT("%d, %s \n", 10, "Hello China!");

    system("pause");
}

//07.C99新語法之行內函數:
//  C語言當中的行內函數用於避免函式不斷的進出棧
//  將該函式保留在特有的棧記憶體當中!(避免不斷進出棧)
__inline void go()
{
    printf("gogogo \n");
}

int main05(void)
{
    go();
    printf("%p \n", go);

    system("pause");
}

相關文章