C:配列の問題

 

文字列処理機能に関連します:

ヘッダ<stdio.hに>なります()、プット()

ヘッダ<string.hの>

(1)、文字列の長さの測定機能:strlenを(名前の文字列)の整数値を返します(「\ 0」を除く)は、文字列内の文字の実際の数を

(2)、文字列の割り当て機能:strcpyの(1つの文字配列名、文字列2)、2列のすべての文字1つ、それはこれまでの記号「\ 0」の終わりに遭遇するまで、文字の配列にコピーし、終了しますで識別子も1文字の配列を書き込みます

              文字列指定された数の割り当て機能:はstrncpy(文字列1、文字列2の数、文字をコピーします)

(3)、文字列連結関数:STRCAT(1つの文字列、列2)、第1ストリング終了フラグは、文字列「\ 0」、スプライシング最初の文字列に2番目の文字列をキャンセル背後に、その結​​果を文字の最初のスプライス配列に格納されています

(4)、文字列比較関数:のstrcmp(文字列1、文字列2)は、辞書に従ってソートを比較する、すなわち、1順次左から右へ行わASCIIコードに応じて最初の文字の2列からない同じ文字又は遭遇フラグが終了するまで、比較、「\ 0」これまでの結果を比較するためには、全体の比較結果として第1の文字列に等しくありません。

       列1及び列2は0を返し、同じ文字に対応する、すなわち同じ長等しいです

    文字列文字列は、正の整数を返し、その後、1〜2よりも大きいです

    2.文字列が負の整数の場合よりも少ないです

strchr(列1、文字2):文字2の最初の出現を検索する文字列(5)、位置

(6)は、文字列1列2の最初の発生を見つける:はstrstr(文字列1、文字列2)

1は、必要とするすべての素数200未満

アルゴリズム分析:

スクリーニング方法をサンプリング:

(1)、それはすべての倍数を遮蔽しながら、2の最小数をとり、それが素数であることを述べたと

(2)数のふるい最小に運ばれていない、それはすべての倍数を遮蔽しながら、それが素数であることを述べたと

(3)を繰り返すステップ(2)は、多数のふるいにすべての素数を与えることです

画面は1であるので、この実施形態は、配列インデックスが数200未満であると、アレイを使用してもよい、セット配列要素を、アレイ素子はそう画面をマークするか、ここで初期値0であります

スクリーニングの効率を向上させるには:

  合成数Nがそれほど数はSQRT(N)よりも小さくない場合、正の因子であること、それは素数であり、SQRT(N)よりも大きい正の因子であるてはなりません

コード:

する#include <stdio.hに> 
する#include <STDLIB.H> 
の#include <math.h>の

空隙のmain()
{ 
    int型プライム[201] = {0}; //ふるいは、非選別に1の値を有するように0 
    ; int型D 
    INTのK; 
    int型I; 

    のため(D = 2; D <= SQRT(200)と; D ++)
    { 
        IF(プライム[D] == 0)
        { 
            (K = 2 * Dのために、Kは< = 200であり、K = K + D)
            { 
                プライム[K] = 1; //画面Dへのすべての倍数
            } 
        } 
    } 

    K = 0; 
    I <= 200である;(I = 2のためのI ++)
    { 
        IF(プライム[ I] == 0)
        { 
            のprintf( "%D \ T"、I); 
            K ++。 
            //出力回線番号5
            もし(K%5 == 0)
            { 
                のprintf( "\ n"); 
            } 
        } 
    } 
}

2、降順に配置されている整数6の配列により平滑化

アルゴリズム分析:使用してバブルソート [毎に、仕分けのために最大n-1回のn順序の数値を、NI比較を渡します]

コード:

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

おすすめ

転載: www.cnblogs.com/pam-sh/p/12384776.html