C: Array Problem

 

Related to the string handling functions:

Header: <stdio.h> gets (), puts ()

Header file: <string.h>

(1), the string length measurement functions: strlen (name character array) returns an integer value: actual number of characters in the string (excluding the '\ 0')

(2), the string assignment function: strcpy (1 character array name, string 2), 2 string all the characters one by one copy to the array of characters until it encounters the end of the sign '\ 0' so far, and will end identifier also write an array of characters in 1

              String specified number assignment function: strncpy (character array 1, the number of the character array 2, the characters to be copied)

(3), string concatenation function: strcat (1 character array, a string 2), the first string end flag cancel a character array '\ 0', splicing the second string to the first string behind, and the results are stored in the first splice array of characters

(4), string comparison function: strcmp (string1, string2), sorted according to the dictionary are compared, i.e., from a string of 1 and 2 of the first character according to the ASCII code sequentially performed from left to right Comparative, not until the end of the same character or encounter flag '\ 0' so far to compare the result is not equal to the first character string as a comparison result of a whole:

       String 1 and string 2 are equal, i.e. the same length, corresponding to the same character, returns 0

    String String is greater than 1 2, then return a positive integer

    2. The character string is less than a negative integer if

(5), the position in the string to find the first occurrence of a character 2: strchr (string 1, character 2)

(6), to find the first occurrence of the string 2 in string 1: strstr (string1, string2)

1, require that all primes less than 200

Analysis of Algorithms:

Sampling screening method:

(1), taking the minimum number of 2, and stated that it is a prime number, while it screens out all its multiples and

(2), is not taken to the sieve smallest in number, stated that it is a prime number, while it screens out all its multiples and

(3) Repeat step (2), to the numerous sieve is to give all primes

This embodiment may use the array that the array index is less than the number 200, the array element so as to mark the screen or not, here the initial value 0 is set array elements, since the screen is 1 to

To improve the screening efficiency:

  A composite number n must be no greater than sqrt (n) is a positive factor, so that if a number is not smaller than sqrt (n) is a positive factor, then it is a prime number

Code:

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

void main () 
{ 
    int Prime [201] = {0}; // sieve to have a value of 1. to unscreened is 0 
    int D; 
    int K; 
    int I; 

    for (D = 2; D <= sqrt (200 is); D ++) 
    { 
        IF (Prime [D] == 0) 
        { 
            for (K = 2 * D; K < = 200 is; K = K + d) 
            { 
                Prime [K] =. 1; // screen to d all multiples 
            } 
        } 
    } 

    K = 0; 
    for (I = 2; I <= 200 is; I ++) 
    { 
        IF (Prime [ I] == 0) 
        { 
            the printf ( "% D \ T", I); 
            K ++; 
            // output line number 5
            if(k % 5 == 0)
            {
                printf("\n");
            }
        }
    }
}

2, by the sequence of integers 6, which are arranged in descending smooth

Algorithm Analysis: using bubble sort [n numbers for ordering, at most n-1 times for sorting, for each pass ni comparisons]

Code:

#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");
}

3、

算法分析:采样直接插入法进行排序

(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]);
    }
}

4、将英语规则名词有单数变为复数,规则如下:

(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);
}

5、明文变密文:

代码:

#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);
}

6、【查找】

 

(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);
}

7、写一个函数,使其能将一个二维数组(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");
    }
}

8、写一个函数,使其能统计主调函数通过实参传送来的字符串,对其中的字母、数字和空格分别计数(要求在主函数中输入字符串及输出统计结果)(参考函数原型: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]用于存储各种字符的个数。
外部变量可以被全部函数共同访问,所以就不需要在统计函数和主函数中分开定义各自的统
计变量,更加方便和节省空间

9、写一个函数,使其能处理字符串中除字母(大小写)、数字外的其他 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);
}

10、设有一个 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");
}

11、写一个函数,使其能求出一元二次方程的解。(参考函数原型: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);
    }
}

12、写一个程序,从键盘输入 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);
}

13、如果一个数正好是它的所有约数(除了它本身以外)的和,此数称完备数,如:6,它的约数有 1、2、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);
}

14、如果有两个数,每一个数它的所有约数(除了它本身以外)的和正好等于对方,则称这两个数为互满数,求出 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);
        }
    }
}

15、函数实现将输入的一组数据逆序输出(参考函数原型: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");
}

Guess you like

Origin www.cnblogs.com/pam-sh/p/12384776.html