1. 程式人生 > >程式設計小練習:最大公約數,字串反序輸出,全排列,不用加減法求和,字串內容反序,字串中最長數字串,陣列是否遞增,陣列反轉,連結串列反轉,翻轉單詞順序

程式設計小練習:最大公約數,字串反序輸出,全排列,不用加減法求和,字串內容反序,字串中最長數字串,陣列是否遞增,陣列反轉,連結串列反轉,翻轉單詞順序

最大公約數 --- 遞迴、非遞迴

#include <stdio.h>

int gcd(int a, int b);
int gcd_recursive(int a, int b);

int main(int argc, char *argv[])
{
        int a, b;
        scanf("%d %d", &a, &b);
        printf("%d %d\n", gcd(a, b), gcd_recursive(a, b));
        return 0;
}

int gcd(int a, int b)
{
        if(b == 0)
                return a;
        while(a%b != 0)
        {
                int temp = a%b;
                a = b;
                b = temp;
        }
        return b;
}

int gcd_recursive(int a, int b)
{
        if(b == 0)
                return a;
        gcd_recursive(b, a%b);
}

字串 --- 遞迴方式反序輸出

  1 #include <stdio.h>
  2 
  3 void reverse(char *p)
  4 {
  5         if(*p == '\0')
  6                 return;
  7         reverse(p+1);   // Note: 此處不能是p++
  8         printf("%c", *p);
  9 }
 10 
 11 int main(int argc, char *argv[])
 12 {
 13         reverse("abc");
 14 
 15         printf("\n");
 16         return 0;
 17 }

全排列

  1 // 全排列
  2 
  3 #include <stdio.h>
  4 
  5 #define swap(a, b) do{\
  6         (a) = (a) ^ (b);\
  7         (b) = (a) ^ (b);\
  8         (a) = (a) ^ (b);\
  9         }while(0)
 10 
 11 void fullOrder(char a[], int begin, int end);
 12 
 13 int main(int argc, char *argv[])
 14 {
 15         char str[] = "ABC";
 16         fullOrder(str, 0, 2);
 17         return 0;
 18 }
 19 
 20 void fullOrder(char a[], int begin, int end)
 21 {
 22         int i;
 23         if(begin >= end)
 24         {
 25                 for(i=0; i<=end; i++)
 26                         printf("%c ", a[i]);
 27                 printf("\n");
 28         }
 29         else
 30                 for(i=begin; i<=end; i++)
 31                 {
 32                         if(begin != i)
 33                                 swap(a[begin], a[i]);
 34                         fullOrder(a, begin+1, end);
 35                         if(begin != i)
 36                                 swap(a[begin], a[i]);
 37                 }
 38 }

兩數求和 --- 不用加減乘除

  1 // 求和
  2 
  3 #include <stdio.h>
  4 
  5 int main(int argc, char *argv[])
  6 {
  7         int a, b;
  8         scanf("%d%*%d", &a, &b);
  9         printf("%d\n", add(a, b));
 10         return 0;
 11 }
 12 
 13 int add(int a, int b)
 14 {
 15         do{
 16                 int sum = a ^ b; // 異或:不考慮進位對每一位相加
 17                 int carry = (a & b) << 1; // 位與、左移:得到進位
 18                 // 將進位與異或的結果相加(求和,即重複前兩步)
 19                 a = sum;
 20                 b = carry;
 21         }while(b != 0); // 直到不產生進位
 22         return a;
 23 }

字串 --- 指標方式將其內容反序

  1 #include <stdio.h>
  2 #include <string.h>
  3 
  4 int main(int argc, char *argv[])
  5 {
  6         char str[] = "ABCD1234efgh";    // 陣列區域性變數
  7         // 此處不能為 char *str = "ABCD1234efgh";
  8         // 否則段錯誤。指標指向的是字串常量區,不能被修改
  9         int len = strlen(str);
 10         char *p = str;
 11         char *q = str + len - 1;
 12 
 13         while(p < q)
 14         {
 15                 char c = *p;
 16                 *p = *q; *q = c;
 17                 p++;    q--;
 18         }
 19 
 20         printf("%s\n", str);
 21         return 0;
 22 }

字串 --- 找出其中連續最長的數字串

  1 #include <stdio.h>
  2 #include <stdlib.h>     // malloc
  3 #include <string.h>
  4 
  5 int findnumstring(char *outputstr, char *inputstr)
  6 {
  7         char *out = outputstr, *in = inputstr;
  8         char *temp, *final;
  9         int count = 0, maxlen = 0;
 10         int i;
 11 
 12         while(*in != '\0')
 13         {
 14                 if(*in>=48 && *in<=57)
 15                         for(temp=in; *in>=48 && *in<=57; in++)
 16                                 count++;
 17                 else
 18                         in++;
 19 
 20                 // 如果temp所指向數字串長度比上一次找到的長
 21                 if(count > maxlen)
 22                 {
 23                         maxlen = count;
 24                         final = temp;
 25                 }
 26                 count = 0;
 27         }
 28 
 29         for(i=0; i<maxlen; i++)
 30                 *out++ = *final++;
 31         *out = '\0';
 32         return maxlen;
 33 }
 34 
 35 int main(int argc, char *argv[])
 36 {
 37         char str[] = "abcd12345eee125ss123456789";
 38         char *res = (char *)malloc(strlen(str) + 1);
 39         int maxlen = findnumstring(res, str);
 40 
 41         printf("%s %d\n", res, maxlen);
 42         free(res);
 43         return 0;
 44 }

陣列 --- 遞迴方式判斷是否為遞增陣列

  1 #include <stdio.h>
  2 
  3 int fun(int *a, int len)
  4 {
  5         if(len == 1)
  6                 return 1;
  7         if(len == 2)
  8                 return (a[len-1] >= a[len-2]);
  9         return (fun(a, len-1) && (a[len-1]>=a[len-2]) );
 10 }
 11 
 12 int main(int argc, char *argv[])
 13 {
 14         int a[] = {1,2,3,4,5};
 15         int b[] = {1,2,5,3,4};
 16 
 17         if(fun(a, 5) == 1)
 18                 printf("a: yes\n");
 19         else
 20                 printf("a: no\n");
 21 
 22         if(fun(b, sizeof(b)/sizeof(b[0])) == 1)
 23                 printf("b: yes\n");
 24         else
 25                 printf("b: no\n");
 26 
 27         return 0;
 28 }

陣列 --- 反轉

 21 void reverse(int arr[], int len)
 22 {
 23         int left = 0;
 24         int right = len-1;
 25         while(left < right)
 26         {
 27                 swap(arr[left], arr[right]);
 28                 left++; right--;
 29         }
 30 }

連結串列 --- 反轉(遞迴、非遞迴)

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 struct node{
  5         int data;
  6         struct node *next;
  7         };
  8 void display(struct node *head);
  9 struct node *reverse(struct node *head);
 10 struct node *reverse_recursive(struct node *head);
 11 
 12 int main(int argc, char *argv[])
 13 {
 14         struct node *head = NULL;
 15         int i;
 16         for(i=0; i<10; i++) // 頭部插入式建立連結串列
 17         {
 18                 struct node *p = (struct node *)malloc(sizeof(struct node));
 19                 p->data = i;
 20                 p->next = head;
 21                 head = p;
 22         }
 23         display(head);
 24         head = reverse(head);
 25         display(head);
 26         head = reverse_recursive(head);
 27         display(head);
 28         return 0;
 29 }
 30 // 非遞迴
 31 struct node *reverse(struct node *head)
 32 {
 33         if(head==NULL || head->next==NULL)
 34                 return head;
 35         struct node *p_pre = head;
 36         struct node *p = head->next;
 37         head->next = NULL;
 38         while(p != NULL)
 39         {
 40                 struct node *p_next = p->next;
 41                 p->next = p_pre;
 42                 p_pre = p;
 43                 p = p_next;
 44         }
 45         return p_pre;
 46 }
 47 // 遞迴
 48 struct node *reverse_recursive(struct node *head)
 49 {
 50         if(head==NULL || head->next==NULL)
 51                 return head;
 52         struct node *temp = head->next;
 53         struct node *p = reverse_recursive(temp); // 遞迴呼叫
 54         temp->next = head;
 55         head->next = NULL;
 56         return p;
 57 }
 58 void display(struct node *head)
 59 {
 60         struct node *p = head;
 61         while(p != NULL)
 62         {
 63                 printf("%d ", p->data);
 64                 p = p->next;
 65         }
 66         printf("\n");
 67 }

strcpy庫函式 --- 實現

char *strcpy(char *dest, const char *src); 返回指標的原因是為了實現鏈式表示式,如 int len = strlen(strcpy(str, "hello"));

  3 char *strcpy(char *dest, const char *src)
  4 {
  5         if(dest==NULL || src==NULL)
  6                 return NULL;
  7         char *ret = dest;
  8         while(*src != '\0')
  9                 *dest++ = *src++;
 10         *dest = '\0';
 11         return ret;
 12 }

反轉數字,123得到321

字元型數值轉換為整型,“123”得123

字元型數值轉換為整型並反轉數字,“123”得321

  1 /*
  2  * FILE: test.c
  3  * DATE: 20180319
  4  * ==============
  5  * DESCRIPTION:
  6  * reverse: 反轉數字,123得到321
  7  * myatoi:字元型數值轉換為整型,“123”得123
  8  * reverse_str_int:字元型數值轉換為整型並反轉數字
  9  */
 10 
 11 #include <stdio.h>
 12 
 13 int main(void)
 14 {
 15         printf("%d\n", reverse(102));
 16         printf("%d\n", myatoi("1abh23"));
 17         return 0;
 18 }
 19 
 20 int reverse(int value)
 21 {
 22         int bits = 1, p = 10;
 23 
 24         while(value >= p) // 計算value長度
 25         {
 26                 p = p * 10;
 27                 bits++;
 28         }
 29         int i, res = 0;
 30         p = 1;
 31         for(i=0; i<bits; i++)
 32         {
 33                 int num = (value/p)%10; // 取每一位的值
 34                 res = res*10 + num;
 35                 p = p * 10;
 36         }
 37         return res;
 38 }
 39 
 40 int myatoi(char *str)
 41 {
 42         char *p = str;
 43         int res = 0;
 44         while(*p)
 45         {
 46                 if(*p>='0' && *p<='9')
 47                         res = res*10 + *p - '0';
 48                 p++;
 49         }
 50         return res;
 51 }
 52 
 53 int reverse_str_int(char *str)
 54 {
 55         int len = 0;
 56         char *p = str;
 57         while(*p++);    // 兩種方法計算字串長度
 58                 //len++;
 59         len = p - str - 1;
 60         p = str + len - 1;
 61         int i, res = 0;
 62         for(i=0; i<len; i++)
 63         {
 64                 if(*p>='0' && *p<='9')
 65                         res = res*10 + *p - '0';
 66                 p--;
 67         }
 68         return res;
 69 }

翻轉單詞順序

  1 /*
  2  * FILE: reverseSentenceWord.c
  3  * DATE: 20180410
  4  * ==============
  5  * DESCRIPTION: 先反轉句子中的所有字元,再反轉每個單詞中的字元
  6  */
  7 
  8 #include <stdio.h>
  9 #include <string.h>
 10 
 11 #define swap(mm, nn) do{\
 12         (mm) = (mm) ^ (nn);\
 13         (nn) = (mm) ^ (nn);\
 14         (mm) = (mm) ^ (nn);\
 15 }while(0)
 16 
 17 void reverseSentenceWord(char *str);
 18 int main(int argc, char *argv[])
 19 {
 20         char str[64];
 21         fgets(str, 64, stdin);
 22         int len = strlen(str);
 23         str[len-1] = '\0';
 24         reverseSentenceWord(str);
 25         printf("%s\n", str);
 26         return 0;
 27 }
 28 
 29 void reverse(char *begin, char *end)
 30 {
 31         if(begin==NULL || end==NULL)
 32                 return;
 33         while(begin < end)
 34         {
 35                 swap(*begin, *end);
 36                 begin++; end--;
 37         }
 38 }
 39 
 40 void reverseSentenceWord(char *str)
 41 {
 42         if(str == NULL)
 43                 return;
 44         char *begin, *end;
 45         begin = end = str;
 46         while(*end != '\0')
 47                 end++;
 48         reverse(begin, --end);
 49         begin = end = str;
 50         while(*begin != '\0')
 51         {
 52                 if(*begin == ' ')
 53                 {
 54                         begin++; end++; // cautious
 55                 }
 56                 else if(*end==' ' || *end=='\0')
 57                 {
 58                         reverse(begin, --end);
 59                         begin = ++end;
 60                 }
 61                 else
 62                         end++;
 63         }
 64 }

校驗IP地址

  1 #include <stdio.h>
  2 #include <string.h>
  3 
  4 int main(int argc, char *argv[])
  5 {
  6         char str[64];
  7         fgets(str, 64, stdin);
  8         int len = strlen(str);
  9         str[len-1] = '\0';
 10         int a, b, c, d;
 11         if(sscanf(str, "%d.%d.%d.%d", &a, &b, &c, &d)==4 && a>=0 && a<=255 && b>=0 && b<=255 && c>=0 && c<=255 && d>=0 && d<=255)
 12         {
 13                 char temp[64];
 14                 sprintf(temp, "%d.%d.%d.%d", a, b, c, d);
 15                 if(strcmp(str, temp) == 0)
 16                         printf("OK\n");
 17                 else
 18                         printf("Error\n");
 19         }
 20         else
 21                 printf("Fail\n");
 22         return 0;
 23 }