C:數組習題

 

與字符串處理有關的函數:算法

頭文件:<stdio.h>    gets()、puts()數組

頭文件:<string.h>函數

(1)、字符串長度測量函數  :strlen(字符數組名),返回一個整型值:字符串中的實際字符數(不包括 '\0')spa

(2)、字符串賦值函數:strcpy(字符數組名1,字符串2),將字符串2的全部字符一個一個複製到字符數組中,直到遇到結束標誌 '\0'爲止,並將結束標識符也寫入字符數組1中blog

              指定數量的字符串賦值函數:strncpy(字符數組1,字符數組2,要複製的字符個數)排序

(3)、字符串鏈接函數:strcat(字符數組1,字符串2),取消第一個字符數組的字符串的結束標誌 '\0' ,把第二個字符串拼接至第一個字符串後面,並把拼接的結果存放到第一個字符數組中字符串

(4)、字符串比較函數 :strcmp(字符串1,字符串2),按字典排序進行比較,即從字符串1和字符串2的第一個字符開始從左至右依次按照 ASCII碼 進行比較,直到出現不相同的字符或者碰到結束標誌 '\0' 爲止,以第一個不相等的字符的比較結果做爲整個字符串的比較1結果:get

       字符串1和字符串2相等,即長度相同,對應的字符也相同,返回0原型

    字符串1大於字符串2,則返回一個正整數字符串處理

    字符串1小於字符2.則返回一個負整數

(5)、查找字符2在字符串1中第一次出現的位置:strchr(字符串1,字符2)

(6)、找到字符串2在字符串1中第一次出現的位置:strstr(字符串1,字符串2)

一、求200之內的全部的素數

算法分析:

採樣篩選法:

(1)、取最小的數2,並聲明它是素數,同時篩去它及它的全部倍數

(2)、取未被篩去的數中最小者,聲明它是素數,同時篩去它及它的全部倍數

(3)、重複步驟(2),至篩中無數爲至,獲得全部的素數

本例可以使用數組,使數組下標就是200之內的數,讓數組元素的值做爲篩去與否的標誌,這裏設數組元素的初值爲0,篩去之後就是1

爲提升篩選效率:

  一個合數n必有一個不大於sqrt(n)的正因子,故一個數如果沒有小於sqrt(n)的正因子,則說明它是一個素數

代碼:

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

void main()
{
    int prime[201] = {0};  // 已篩去的值爲1.未篩去的值爲0
    int d;
    int k;
    int i;

    for(d = 2;d <= sqrt(200);d++)
    {
        if(prime[d] == 0)
        {
            for(k = 2*d;k <= 200;k = k + d)
            {
                prime[k] = 1;  // 篩去d的全部倍數
            }
        }
    }

    k = 0;
    for(i = 2;i <= 200;i++)
    {
        if(prime[i] == 0)
        {
            printf("%d\t",i);
            k++;
            //一行輸出5個數
            if(k % 5 == 0)
            {
                printf("\n");
            }
        }
    }
}

二、將由6個整數組成的序列,將其按從大到小的順利排列

算法分析:使用冒泡排序法【對於n個數排序,至多進行n-1 遍排序,每遍進行n-i 次比較】

代碼:

#include <stdio.h>
#include <stdlib.h>
const int n = 6;

void main()
{
    int a[n];
    int i;
    int j;
    int temp;

    //輸入
    printf("請輸入待排序元素:\n");
    for(i = 0;i < n;i++)
    {
        printf("a[%i]=",i);
        scanf("%d",&a[i]);
    }

    //排序
    for(i = 1;i < n;i++)
    {
        for(j = 0;j < n-i;j++)
        {
            if(a[j] < a[j+1])
            {
                temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }

    //輸出
    printf("排序後從大到小輸出:\n");
    for(i = 0;i < n;i++)
    {
        printf("%d\t",a[i]);
    }
    printf("\n");
}

因爲對什麼樣的數據都會掃描n-1遍,包括已經排好序的也會掃描n-1遍

改進:設置一個變量change 表示一遍掃描中是否會進行交換,在每一遍掃描開始時,將其設置爲,表示未交換;在掃描中若是進行了交換,則將變量設置爲1,本遍掃描完成後,若是change=0,則表示本遍掃描中未進行交換,便可退出掃描。

代碼:

//改進
void main()
{
    int a[n];
    int i;
    int j;
    int temp;
    int change;

    //輸入
    printf("請輸入待排序元素:\n");
    for(i = 0;i < n;i++)
    {
        printf("a[%i]=",i);
        scanf("%d",&a[i]);
    }

    //排序
    for(i = 1;i < n;i++)
    {
        change = 0;
        for(j = 0;j < n-i;j++)
        {
            if(a[j] < a[j+1])
            {
                temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
                change = 1;
            }
        }
 if(change = 0) { break; }
    }

    //輸出
    printf("排序後從大到小輸出:\n");
    for(i = 0;i < n;i++)
    {
        printf("%d\t",a[i]);
    }
    printf("\n");
}

直接插入法實現:

//直接插入法實現
void main()
{
    int a[n];
    int i;
    int j;
    int temp;

    //輸入
    printf("請輸入待排序元素:\n");
    for(i = 0;i < n;i++)
    {
        printf("a[%i]=",i);
        scanf("%d",&a[i]);
    }

    //排序
    for(i = 1;i < n;i++)
    {
        j = i - 1;
        temp = a[i];
        while((a[j] < temp) && (j >= 0))
        {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = temp;
    }

    //輸出
    for(i = 0;i < n;i++)
    {
        printf("%d\t",a[i]);
    }
    printf("\n");
}

直接插入法改進:

//直接插入法實現改進
void main()
{
    int a[n];
    int i;
    int j;
    int change;
    int temp;

    //輸入
    printf("請輸入待排序元素:\n");
    for(i = 0;i < n;i++)
    {
        printf("a[%i]=",i);
        scanf("%d",&a[i]);
    }

    //排序
    for(i = 1;i < n;i++)
    {
        j = i - 1;
        temp = a[i];
        change = 0;
        while((a[j] < temp) && (j >= 0))
        {
            a[j + 1] = a[j];
            j--;
           change = 1;
        }
        a[j + 1] = temp;
 if(change = 0) { break; }
    }

    //輸出
    for(i = 0;i < n;i++)
    {
        printf("%d\t",a[i]);
    }
    printf("\n");
}

三、

算法分析:採樣直接插入法進行排序

(1)、用數組a存儲待排序元素,n存儲待排序元素的個數

(2)、讓 i 表示排序的遍數,其值爲從2到n

(3)、在每趟排序中,a[1],a[2],a[3]。。。,a[i-1] 已經排好序,以a[0] 爲監視哨,將a[i]依次與a[i-1],a[i-2],.............,a[0]比較,即令循環變量j = i -1, i - 2, .... , 0 

(4)、若是a[0] < a[j] ,則將a[j] 後移,不然終止此循環

(5)、將a[j + 1]的值賦爲a[o]

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

void main()
{
    static int a[] = {23,56,234,1,45,34,21,394,3,35};
    int i,j,temp;

    //排序
    for(i = 1;i < 10;i++)
    {
        j = i - 1;
        temp = a[i];   //前面i-1個元素已經排好序
        while((a[j] > temp) && (j >= 0))
        // 把前面i-1個元素中比a[i]大的元素依次後移
        {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = temp;   // 把a[i]插入到正確的位置
    }

    //輸出
    for(i = 0;i < 10;i++)
    {
        printf(" %d",a[i]);
    }
    printf("\n");
}

改進:使用a[0] 做爲監視哨,免去查找過程當中每一步都要檢測的數組是否越界的問題

代碼:

#include <stdio.h>
#include <stdlib.h>
const int n = 10;

//改進
void main()
{
    int a[n+1];
    int i,j;
    //輸入
    for(i = 1;i <= n;i++)
    {
        printf("請輸入待排序數a[%d]:",i);
        scanf("%d",&a[i]);
    }
    //排序
    for(i = 2;i <= n;i++)
    {
        a[0] = a[i];
        for(j = i - 1;a[0] < a[j];j--)
        {
            a[j + 1] = a[j];
        }
        a[j + 1] = a[0];
    }
    //輸出
    for(i = 1;i <= n;i++)
    {
        printf("%d\t",a[i]);
    }
}

四、將英語規則名詞有單數變爲複數,規則以下:

(1)、以字母y結尾,且y前面是一個輔音字母,則將y 變 i ,再加es;

(2)、以s、x、ch、sh結尾,則加es

(3)、以字母o結尾,則加es

(4)、其餘狀況直接加s

代碼:

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

void main()
{
    char word[100];
    int len;
    printf("請輸入一個單詞:");
    scanf("%s",word);
    len = strlen(word);  //求單詞長度

    // 若以y結尾
    if((len > 1) && (word[len - 2] != 'a') && (word[len - 2] != 'e') && (word[len - 2] != 'i') && (word[len - 2] != 'o') && (word[len - 2] != 'u') && (word[len - 1] == 'y'))
    {
        word[len - 1] = 'i';
        word[len] = 'e';
        word[len + 1] = 's';
        word[len + 2] = '\0';
    }
    //若以s、x、ch、sh結尾
    else if((word[len - 1] == 's') || (word[len - 1] == 'x') || (len > 1 && word[len - 1] == 'h' && (word[len - 2] == 'c' || word[len - 2] == 's')))
    {
         word[len] = 'e';
         word[len + 1] = 's';
         word[len + 2] = '\0';
    }
    //以o結尾
    else if(word[len - 1] == 'o')
    {
          word[len] = 'e';
          word[len + 1] = 's';
          word[len + 2] = '\0';
    }
    //其餘方式結尾
    else
    {
        word[len] = 's';
        word[len + 1] = '\0';
    }
    printf("單詞的複數形式爲:%s\n",word);
}

五、明文變密文:

代碼:

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

void main()
{
    char str1[200]; //存儲明文
    char str2[200];  //存儲密文
    int num;
    int len = 0;
    int i;
    //輸入明文
    printf("請輸入明文:");
    gets(str1);
    //求明文長度
    len = strlen(str1);

    for(i = 0;i < len;i++)
    {
        num = -1;  //初始化字母序列
        //處理小寫字母
        if(str1[i] <= 'z' && str1[i] >= 'a')
        {
            num = str1[i] - 'a' + 1;
            num = num * 3 % 52;
        }
        //處理大寫字母
        else if(str1[i] <= "Z" && str1[i] >= "A")
        {
            num = str1[i] - 'A' + 27;
            num = num *3 % 52;
        }
        //密文爲小寫字母
        if(num > 0 && num <= 26)
        {
            str2[i] = num + 'a' - 1;
        }
        //密文爲大寫字母
        else if(num >= 27 && num <= 51)
        {
            str2[i] = num +'A' - 27;
        }
        //密文爲Z
        else if(num == 0)
        {
            str2[i] = 'Z';
        }
        //密文爲其餘字符
        else
        {
            str2[i] = str1[i];
        }
    }
    //爲密文加上結束標誌
    str2[i] = '\0';
    printf("密文是:%s\n",str2);
}

六、【查找】

 

(1)、從前向後依次查找

代碼:

#include <stdio.h>
#include <stdlib.h>
const int n = 7;

void main()
{
    int a[n + 1];
    int i,j,x;
    //輸入
    for(i = 1;i <= n;i++)
    {
        printf("請輸入a[%d]:",i);
        scanf("%d",&a[i]);
    }
    printf("請輸入待查元素:");
    scanf("%d",&x);
    //查找
    for(i = 1;i <= n;i++)
    {
        if(a[i] == x)
        {
            break;
        }
    }
    if(i <= n)
    {
        printf("%d\n",i);
    }
    else
        printf("%d\n",0);
}

(2)、從後向前,依次查找,故結束後沒必要對i的值進行比較

代碼:

void main()
{
    int a[n + 1];
    int i,j,x;
    //輸入
    for(i = 1;i <= n;i++)
    {
        printf("請輸入a[%d]:",i);
        scanf("%d",&a[i]);
    }
    printf("請輸入待查元素:");
    scanf("%d",&x);
    //查找
    for(i = n;i >= 1;i--)
    {
        if(a[i] == x)
        {
            break;
        }
    }
    printf("%d\n",i);
}

(3)、使用監視哨 ,免去查找過程當中每一步都要檢測的數組是否越界的問題

 代碼:

void main()
{
    int a[n + 1];
    int i,j,x;
    //輸入
    for(i = 1;i <= n;i++)
    {
        printf("請輸入a[%d]:",i);
        scanf("%d",&a[i]);
    }
    printf("請輸入待查元素:");
    scanf("%d",&x);
    //查找
    a[0] = x;  //若到i = 0時,退出循環,i = 0
    for(i = n;a[i] != x;i--);
    printf("%d\n",i);
}

(4)、折半查找  【必須爲有序數組】

算法思想:

 

 代碼:

void main()
{
    int a[n + 1];
    int i,x,low = 1,high = n,mid;
    //輸入
    for(i = 1;i <= n;i++)
    {
        printf("請輸入有序數字a[%d]:",i);
        scanf("%d",&a[i]);
    }
    printf("請輸入待查元素:");
    scanf("%d",&x);
    //查找
    while(low <= high)
    {
        mid = (low + high) / 2;
        if(x == a[mid])
            break;
        else if(x < a[mid])
            high = mid - 1;
        else
            low = mid + 1;
    }
    //輸出
    if(x == a[mid])
    {
        printf("%d\n",mid);
    }
    else
        printf("%d\n",0);
}

七、寫一個函數,使其能將一個二維數組(5×3)中的數據進行行列互換(參考函數 原型:void tran(int array[5][3]))

 代碼:

#include <stdio.h>
#include <stdlib.h>
int b[3][5];   //外部二維數組,能夠被所有函數訪問

void tran(int array[5][3])//定義轉秩函數,無返回值
{
    int i,j;
    for(i=0; i<5; i++)
        for(j=0; j<3; j++)
            b[j][i]=array[i][j];//交換
}
main()
{
    int i,j;
    int a[5][3]= {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
    printf("交換前是:\n");
    for(i=0; i<5; i++)
    {
        for(j=0; j<3; j++)
            printf("%4d",a[i][j]);
        printf("\n");
    }
    tran(a);//調用交換函數實現對數組 a 的轉秩
    printf("\n 交換後是:\n");
    for(i=0; i<3; i++)
    {
        for(j=0; j<5; j++)
            printf("%4d",b[i][j]);
        printf("\n");
    }
}

八、寫一個函數,使其能統計主調函數經過實參傳送來的字符串,對其中的字母、數字和空格分別計數(要求在主函數中輸入字符串及輸出統計結果)(參考函數原型:void count(char* str))

 代碼:

#include <stdio.h>
#include <stdlib.h>
int b[3];  //定義外部變量,用於存儲各類字符的個數

void count(char *str)//定義統計函數
{
    while((*str)!=0)
    {
        if(('a'<=*str&&*str<='z')||('A'<=*str&&*str<='Z'))//求字符個數
            b[0]++;
        if('0'<=*str&&*str<='9')//求數字個數
            b[1]++;
        if(*str==' ')//空格個數
            b[2]++;
        str++;
    }
}
void main()
{
    char str[100];
    printf("請輸入字符串:\n");
    gets(str);
    printf("字符串%s 中",str);
    count(str);//調用統計函數
    printf("\n 字母個數:%d",b[0]);
    printf("\n 數字個數:%d",b[1]);
    printf("\n 其空格個數:%d",b[2]);
}

程序分析:

  定義了一個外部數組變量 b[3]用於存儲各類字符的個數。
外部變量能夠被所有函數共同訪問,因此就不須要在統計函數和主函數中分開定義各自的統
計變量,更加方便和節省空間

九、寫一個函數,使其能處理字符串中除字母(大小寫)、數字外的其餘 ASCII 字符,對多於一個連在一塊兒的相同字符,將其縮減至僅保留一個。(參考函數原型:void del(char*str))

算法分析:

  難點在於處理連在一塊兒的相同字符。首先定 義一個字符數組 str2[ ],用於存儲判斷處理後的字符串。字符串 str 開始循環後,若是是字母或者數字,就賦給 str2;若是是其餘字符,先判斷是否爲連續,再進行賦值。連續的狀況須要特殊處理,循環直到是其餘字符後再賦值。

代碼:

#include <stdio.h>
#include <stdlib.h>
char str2[80];//定義一個數組存儲字符串

void del(char *str)//定義函數
{
    int i=0;
    while((*str)!=0)
    {
        if(('a' <= *str && *str <= 'z')||('A' <= *str && *str <= 'Z')||('0' <= *str && *str <= '9'))//判斷 ASCII 碼
        {
            str2[i]=*str;
            str++;
            i++;
        }
        else//處理連在一塊兒的相同其餘字符
        {
            while(*str==*(str+1))
                str++;
            str2[i]=*str;
            str++;
            i++;
        }
    }
}
void main()
{
    char str[80];
    printf("請輸入字符串:");
    gets(str);
    del(str);
    printf("\n新字符串:%s\n",str2);
}

十、設有一個 3 位數,將它的百、十和個位 3 個單一數,各自求立方,而後加起來,正好等於這個 3 位數,如 153=1+125+27。寫一個函數,找出全部知足條件的數。(參考函數原型:int find(int n))

代碼:

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

int find(int n)
{
    int i,j,k; //i 表示百位,j 表示十位,k 表示個位
    int flag; //標誌位,是否知足條件
 i = n / 100; //求百位 j = n / 10 - i * 10; //求十位 k = n % 10; //求個位
    if(n == i * i * i + j * j * j + k * k * k) //判斷
        flag = 1;
    else
        flag = 0;
    return flag;
}
void main()
{
    int f,n;
    printf("符合條件的數有:");
    for(n = 100; n < 1000; n++) //循環判斷全部的三位數
    {
 f = find(n); if(f)
            printf("%4d",n);
    }
    printf("\n");
}

十一、寫一個函數,使其能求出一元二次方程的解。(參考函數原型:void s(int a,int b,intc),a、b、c 分別表明一元二次方程的係數)

代碼:

#include <stdio.h>
#include <stdlib.h>
float x1,x2;

void s(int a,int b,int c)
{
    int s;12
 s = b * b -4 * a * c; //求兩個解 x1 = (sqrt(s) - b) / (2 * a); x2 = (-sqrt(s) - b) / (2 * a);
}
main()
{
    int a,b,c;
    printf("請輸入一元二次方程的係數:");
    scanf("%d,%d,%d",&a,&b,&c);
    if(a == 0)//去掉 a 爲 0 的不合法方程
    {
        printf("a 不能爲 0!\n");
    }
    else
    {
        s(a,b,c);
        printf("方程的解爲:%f 和%f\n",x1,x2);
    }
}

十二、寫一個程序,從鍵盤輸入 5 個正整數,而後求出它們的最小公倍數,並顯示輸出(經過調用對兩個正整數求最小公倍數的函數實現)(參考函數原型:int find(int i,int j))

代碼:

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

int find(int i,int j)
{
 int temp,a,b; if(i<j)//保證用較大的數除以較小的數 { temp=i; i=j; j=temp; } a=i; b=j; while(b!=0)//展轉相除 { temp=a%b; a=b; b=temp; } return(i*j/a);
}
main()
{
    int a[5],b,i;
    printf("請輸入 5 個整數:");
    for(i=0; i<5; i++)
        scanf("%d",&a[i]);
    b=find(a[0],a[1]);//調用函數對 5 個整數進行處理
    b=find(b,a[2]);
    b=find(b,a[3]);
    b=find(b,a[4]);
    printf("5 個整數的最小公倍數是%d\n",b);
}

1三、若是一個數正好是它的全部約數(除了它自己之外)的和,此數稱完備數,如:6,它的約數有 一、二、3,而且 1+2+3=6。求出 30 000 之內全部的完備數,並顯示輸出(求完備數用函數實現)(參考函數原型:void find(int j),直接在子函數中輸出完備數及其全部約數)

 算法分析:

對於整數 j,要求出全部的約數,須要對小於 j 的全部數進行循環。在每求

出一個約數的同時,j 減去這個約數,再將結果賦給 j,若是是完備數,最後的結果將是 0。
須要注意是的,j 的值在不斷變化,爲了保證 j 一直用初值進行求約數操做,因此首先將 j
的值賦給一箇中間變量 s,利用 s 來進行減操做,讓兩步操做不相互影響。

代碼:

#include <stdio.h>
#include <stdlib.h>
int k[20];

void find(int j)
{
 int i,n,s;//i 爲因子 n = -1; s=j; for(i=1; i<j; i++) { if((j%i)==0) { n++; s = s - i; k[n]=i;//將每一個因子賦給數組 k } } if(s==0) { printf("%d 是一個完備數,它的因子是:",j); for(i=0; i <= n; i++) printf("%6d",k[i]);//輸出 printf("\n"); }
}
main()
{
    int n;
    printf("符合條件的數有:\n");
    for(n=1; n<30000; n++)
        find(n);
}

1四、若是有兩個數,每個數它的全部約數(除了它自己之外)的和正好等於對方,則稱這兩個數爲互滿數,求出 30 000 之內全部的互滿數,並顯示輸出。求一個數它的全部約數(除了它自己之外)的和用函數實現(參考函數原型:int factor(int j))

代碼:

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

int k[40];
#define N 30000
int factor(int j)
{
    int i,n,s;//i 爲因子
    n = -1;
    s=j;
    for(i=1; i<j; i++)
    {
        if((j%i)==0)
        {
            n++;
            s = s - i;
            k[n]=i;//將每一個因子賦給數組 k
        }
    }
    s=1;
    for (i=1; i<=n; i++)s+=k[i]; // 將每一個因子累加
    return s;
}
void main()
{
    int s1,s2,m,n;
    for (m=2; m<N; m++)
    {
        s1=factor(m);
       for (n=m+1; n<N; n++)
        {
            s2=factor(n);
            if(s1==s2)
                printf("%d和%d是互滿數\n",m,n);
        }
    }
}

1五、函數實現將輸入的一組數據逆序輸出(參考函數原型:void isort(int a[]))

算法分析:

  長度爲 n 的數組 a[n]逆序的實現方法就是將 a[i]和 a[n−i−1]交換。  

代碼:

#include <stdio.h>
#include <stdlib.h>
#define N 5

void isort(int a[])
{
    int i,temp;
    for(i=0; i<N/2; i++) //交換 { temp=a[i]; a[i] = a[N - i - 1]; a[N - i - 1] = temp; }
}
main()
{
    int a[N],i;
    printf("請輸入%d 個數據:\n",N);
    for(i=0; i<N; i++)
        scanf("%d",&a[i]);
    isort(a);
    printf("逆序輸出的結果是:");
    for(i=0; i<N; i++)
        printf("%d\t",a[i]);
    printf("\n");
}
相關文章
相關標籤/搜索