zoukankan      html  css  js  c++  java
  • C语言数组

    引用:

    int a,b,c,d,......

    int sum

    =>

    定义一类或一组变量

    数组

    1.数组是什么?

    数组是一组具有相同类型的数据(变量)的集合

    C语言中数组:

    一维数组

    二维数组

    三维数组

    ...

    其实,C语言中只有一维数组

    2,一维数组

    2.1 定义格式

    类型说明符 数组名[整型表达式] {={初始化列表}};

    {}: 可要可不要

    "类型说明符":指定数组元素的类型,任意C语言合法的类型都可以

    数组名”:对象的名字,命名要符合C语言标识符的规定

    整型表达式” :指定数组中元素的个数,一般为常量表达式

    eg:

    #define N 3

    int a[10];//定义了一个数组,数组名a,里面有10int型元素

    typeof(a)  =>一个具有10int元素的数组类型 int[10]

    char b[10];

    typeof(b)  => 一个具有10char元素的数组类型 char[10]

    int c;//在程序运行的时候,为c分配4个字节的空间

    在程序运行的时候,为a分配多大的空间?

     10int =40个字节

    sizeof(a) =>40

    2.2 一维数组在内存中的存放

    在连续的地址空间中,从低地址到高地址依次存放数组中的每个元素。

    意思:第二个元素只能紧跟着第一个元素后面存放

    int a[10];

    0x0001  -> 第一个元素

    0x0005  -> 第二个元素

    ....

    2.3一维数组元素的引用

    int a[10];

    引用方式:

    数组名[下标];//C语言的下标是从0开始

    a[0] 数组中第一个元素

    ...

    a[9]

    引用数组元素a[i] 和引用普通变量是一样的,都有左值和右值,还可以取地址

    eg:

    int  b;

    b = 1024;

    a[0] = 1024;//表示数组元素a[0]的地址

    b = a[0]; //表示数组元素a[0]的值

    练习:

    定义一个整型数组,数组中有10个元素。从键盘上输入值来给元素赋值

    然后把整个数组输出

    int a[10];

    for(i = 0; i<10;i++)

    {

    scanf("%d",&a[i]);

    }

    printf("%d ",a);

    2.4 一维数组的初始化

    初值是存在一对花括号中

    (1)数组元素全部初始化

    int a[10] = {1,2,3,4,5,6,7,8,9,10};

    eg:

    int a[10];

    a[10] = {1,2,3,4,5,6,7,8,9,10};//error

    (2)可以只对部分元素初始化,后面的元素自动初始化为0

    int a[10] = {1,2,3};

    把整个数组初始化为0

    int a[10] = {0};

    (3)如果对全部元素初始化,那么在定义数组的时候,可以不指定数组的长度

    why?

    int a[] = {1,2,3};

    ☆☆

    char s[] = {'a','b','c'};

    =>数组s里面有3个元素

    printf("%s",s);

    char s1[10] = {'a','b','c'};

    printf("%s",s1);

    “字符串长度” :就是从一个起始地址的内容开始找,找到第一个为止

    前面有多少个字符,那就是字符串的长度

    数组的长度 :数组有多少个元素

    eg:

    int a[10];

    sizeof(a)/sizeof(a[0])

    字符数组的大小:这个数组所占空间的大小

    sizeof(s) => 3

    sizeof(s1) => 10

    练习:

    1)求一个一维数组(int)中元素之和

    最大值,最小值 3.c

    "遍历" :对某个对象中每个元素访问且仅访问一次

    int x,i,max,min,sum;

    scanf("%d",&x);

    int a[x];

    max = a[0];

    min = a[0];

    for(i = 0;i <x;i++)

    {

    scanf("%d",&a[i]);

    }

    for(i = 0; i < x;i++)

    {

    if(max < a[i])

    {

    max = a[i];

    }

    if(min > a[i])

    {

    min = a[i];

    }

    }

    printf("max = %d,min = %d ",max,min);

    2Fibonacci(斐波那契数列前20项之和)

    1 1 2 3 5 8 13 21 ...

    从第三项开始,每一项都是前面两项之和

    int Fi[20] = {1,1};

    int sum = 2;

    Fi[2] = Fi[1] +Fi[0];

    sum += Fi[2];

    Fi[3] = Fi[2] +Fi[1];

    sum += Fi[3];

    ...

    for(i = 2;i < 20;i++)

    {

    Fi[i] = Fi[i-1] +Fi[i-2];

    sum += Fi[i];

    }

    3)给定一个一维数组(int),判断是否为递增数组

    a[0] < a[1] <a[2] <a[3]...a[n-1]

    int x,i;

    scanf("%d",&x);

    int a[x];

    int flag = 1;//递增标志位 1 :递增 ,0 :非递增

    for(i = 0;i <x;i++)

    {

    scanf("%d",&a[i]);

    }

    for(i = 0;i < x-1;i++)

    {

    if(a[i] >= a[i+1] )

    {

    flag = 0;

    break;

    }

    }

    /*

    if(i == x-1)

    {

    printf("yes ");

    }

    */

    if(flag)

    {

    printf("yes ");

    }

    (4)在一个给定的升序的一维数组中,查找一个元素

    int a[10];

    查找数组a中是否有元素x,有就打印yes,没有就打印no

    二分法/二分查找法

    代码

    int find(int n,int a[],int l)
    {
    int low=0;
    int high=l-1;
    int middle=0;
    while(low<high)
    {
    middle=(low+high)>>1;
    if(n==a[middle])
    {
    printf("%d,%d",n,middle);
    return 1;

     

    }
    else if(n>a[middle])
    low=middle+1;

    else
    high=middle-1;

    }

     

    return 0;

    }

     

    int main()

    {
    int a[]={2,3,5,6,7,8,9,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60};
    int l=sizeof(a)/sizeof(a[0]);
    int i=0,n;
    printf("arry content");
    for(i=0;i<l;i++)
    {
    if(i%8==0)
    printf(" ");
    printf("%4d",a[i]);



    }
    printf(" seach n is ");
    scanf("%d",&n);
    if(!find(n,a,l))
    printf("not fond");
    return 0;

    }

     

     

    二分查找的基本思想是:(设R[low..high]是当前的查找区间)
     1)首先确定该区间的中点位置:
                     
     2)然后将待查的K值与R[mid].key比较:若相等,则查找成功并返回此位置,否则须确定新的查找区间,继续二分查找,具体方法如下:
         R[mid].key>K,则由表的有序性可知R[mid..n].keys均大于K,因此若表中存在关键字等于K的结点,则该结点必定是在位置mid左边的子表R[1..mid-1]中,故新的查找区间是左子表R[1..mid-1]
         类似地,若R[mid].key<K,则要查找的K必在mid的右子表R[mid+1..n]中,即新的查找区间是右子表R[mid+1..n]。下一次查找是针对新的查找区间进行的。
         因此,从初始的查找区间R[1..n]开始,每经过一次与当前查找区间的中点位置上的结点关键字的比较,就可确定查找是否成功,不成功则当前的查找区间就缩小一半。这一过程重复直至找到关键字为K的结点,或者直至当前的查找区间为空(即查找失败)时为止。

     

    二分查找算法
        int BinSearch(SeqList RKeyType K)
          { //在有序表R[1..n]中进行二分查找,成功时返回结点的位置,失败时返回零
            int low=1high=nmid//置当前查找区间上、下界的初值
            while(low<=high){ //当前查找区间R[low..high]非空
              mid=(low+high)/2
              if(R[mid].key==K) return mid//查找成功返回
              if(R[mid].kdy>K)
                 high=mid-1; //继续在R[low..mid-1]中查找
              else
                 low=mid+1//继续在R[mid+1..high]中查找
             }
            return 0//low>high时表示查找区间为空,查找失败
           } //BinSeareh

     

    二分查找的优点和缺点
      虽然二分查找的效率高,但是要将表按关键字排序。而排序本身是一种很费时的运算。既使采用高效率的排序方法也要花费O(nlgn)的时间。
      二分查找只适用顺序存储结构。为保持表的有序性,在顺序结构里插入和删除都必须移动大量的结点。因此,二分查找特别适用于那种一经建立就很少改动、而又经常需要查找的线性表。
      对那些查找少而又经常需要改动的线性表,可采用链表作存储结构,进行顺序查找。链表上无法实现二分查找。

    a:1 2 3 5 6 8 9    x = 4

    l = 0

    r = 6

    mid = 3

    =>

    l = 0

    r = mid-1 = 2

    mid = 1

    =>l = mid+1 = 2

      r = 2

      mid = 2

      

     =>l = mid+1 = 3

    r = 2

    int a[n];

    int l = 0,r = n-1;

    while(l <= r)

    {

    mid = (l+r)/2;//范围[l,r]中间元素的下标

    if(a[mid] == x)

    {

    break;

    }

    else if(a[mid] > x)

    {

    r = mid-1;

    }

    else

    {

    l = mid+1;

    }

    }

    作业:

    因式分解

    90 = 2*3*3*5

    15

    1)将一个一维数组(int)排序

    2)一个一维数组中有正有负,写一个程序,把数组中负数放在正数的前面

    3)求一个一维数组中第二大的元素

    考虑有重复的元素

    4)一维数组的插入排序

    答案

    作业:

    0因式分解

    90 = 2*3*3*5

    15

    算法1

    sum=1;

    num1 = num;

    for(i=2i<num)

    {

    if(num%i==0)

    {

    sum*=i;

    a[x]=i;

    x++;

    num/=i;

    }

    else

    i++;

    if(sum==num1)

    break;

    }

    算法2

    90

    [2,n/2]

    for(i = 2;i <= n/2;i++)

    {

    while(n%i == 0)

    {

    printf("%d*",i);

    n /= i;

    }

    }

    printf("%d ",n);

    90

    1)将一个一维数组(int)排序

    冒泡排序:

    两两比较,大的往后移

    9 7 8 4 2

    7 9 8 4 2

    7 8 9 4 2

    7 8 4 9 2

    7 8 4 2 9

    if(a[0] > a[1])

    {

    a[0] <-> a[1]

    }

    if(a[1] > a[2])

    {

    a[1] <-> a[2]

    }

    ...

    if(a[i] > a[i+1])

    {

    a[i] <-> a[i+1]

    }

    for(i = 0;i < N-1;i++)

    {

    if(a[i] > a[i+1])

    {

    a[i] <-> a[i+1]

    }

    }//一趟冒泡

    for(j = 0;j < N;j++)

    {

    for(i = 0;i < N-j;i++)

    {

    if(a[i] > a[i+1])

    {

    a[i] <-> a[i+1]

    }

    }

    }

    选择排序:

    从待排序的数组中,选择最大的那个元素与最后面的那个元素进行交换

    4 8 2 6 3

    i = 0;

    if(a[1] < a[0])

    {

    a[1] <-> a[0]

    }

    if(a[2] < a[0])

    {

    a[1] <-> a[0]

    }

    if(a[N-1] < a[0])

    {

    a[1] <-> a[0]

    }

    ====

    for(i = 0;i < N;i++)

    {

    for(j = i+1;j < N;j++)

    {

    if(a[j] < a[i])

    {

    a[1] <-> a[0]

    }

    }

    }

    ===========

    2)一个一维数组中有正有负,写一个程序,把数组中负数放在正数的前面

    -3 4 9 -2 -3

    =>

    int next = 0;

    for(i = 0;i < N;i++)

    {

    if(a[i] < 0)

    {

    a[next] <->a[i]

    next++;

    }

    }

    3)求一个一维数组中第二大的元素

    考虑有重复的元素

    9 9 8 8 8

    max = a[0];

    second = [1];

    for(i =0;i < M;i++)

    {

    if(a[i] > max)

    {

    second = max;

    max = a[i];

    }

    }

    4)一维数组的插入排序二分法

    int a[10];

    int l,r,mid;

    for(i = 0;i < 10;i++)

    {

    scanf("%d",&a[i]);

    //排序

    //找插入位置

    //二分法/二分查找法

    l = 0;

    r = i;

    while(l <= r)

    {

    mid = (l+r)/2;

    if(a[mid] == a[i])

    {

    break;

    }

    else if(a[mid] < a[i])

    {

    l = mid+1;

    }

    else

    {

    r = mid-1;

    }

    }

    //插入操作

    //把插入位置及后面的元素,每一个都往后移

    x = a[i];

    //mid,...i-1

    for(j = i-1;j >= mid;j--)

    {

    a[j+1] = a[j];

    }

    a[mid] = x;

    }

    7 5 6 3 2 4

    5   6         7

    mid     i-1  i

    回顾:

    一维数组

    定义:

    数据元素的类型 数组名[数组元素个数];

    int a[4];

    数组a中有4个元素 a[0] a[1] a[2] a[3] ,每个元素int

    typeof(a) =>int[4]

    =>假如我们要定义3个像a这种类型的对象

    对象 =》数组

    typeof(a) b[3];

    =>b数组名,它里面有3个元素,分别是b[0],b[1],b[2]

    并且这三个元素都是typeof(a)

    typeof(a) =>int[4]

    int[4] b[3];

    b[0]   _ _ _ _

    b[1]   _ _ _ _

    b[2]   _ _ _ _

    每个元素代表着一个一维数组,且每个里面有4int

    int[4] b[3]; //关键字不能与[]在一块

    int b[3][4];

    二维数组实际上是一个一维数组,只不过该一维数组中的元素又是一个一维数组

    1.二维数组

    1.1二维数组的实质

    是一个一维数组

    1.2 二维数组的定义

    类型说明符 数组名[常量表达式(行大小)][常量表达式(列大小)];

    1.3 二维数组在内存中的存放

    int a[3][4];

    sizeof(a) => 3*4*4

    按行存放,即先存放第一行的元素,在放第二行的元素

    1.4 二维数组的引用

    数组名[行下标][列下标]

    下标:从0开始

    1.5 二维数组的初始化

    (1)分行给二维数组赋初值

    int b[3][4];

    typeof(b) =>int[4][3]

    int b[3][4] = {

    {1,2,3,4},//b[0]

    {2,3,4,5},//b[1]

    {3,4,5,6}//b[2]

    };

    (2)将所有数据写在一个花括号内,按数组排列顺序对各元素赋初值

    int b[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

    (3)对部分元素赋初值,其余元素自动置0

    int b[3][4] = {{1},{2,3},{4,5}};

    or

    int b[3][4] = {1,2,3,4};

    (4)如果对全部元素赋初值,则定义数组时对第一维的长度省略,但第二维的长度不可以

    int [][4] = {1,2,3,4,5,6,7,8};

    2.字符数组

    元素都是字符形式

    字符串的结束标志 ''

    char s[] = {'a','b','c',''};

    %s :格式符 输出字符串

     遇到第一个结束

    printf("%s ",s);

    字符串的操作函数:

    strlen :求字符串的长度,

    遇到第一个结束

    strlen("gvjh") =>4

    strcmp :字符串的比较函数

    strcmp(s1 ,s2)

    s1 > s2 return 1

    s1 == s2  return 0

    s < s2   return -1

    strcat :字符串连接函数

    s1 : "1234"

    s2 : "asdf"

    strcat(s1,s2);

     =>1234asdf

    strcpy :字符串拷贝

    s1 : "1234"

    s2 : "asdf"

    strcpy(s1,s2);

     =>asdf

    练习:

    1)定义一个整型二维数组,从键盘上给各个元素赋值

    在把整个数组输出

    2)求一个二维数组的最大值,最小值,及所有元素的和

    3)求一个二维数组中列元素之和最大的那个列

    int a[3][4]

    (1)构造一个一维数组b[4],用来保存目标二维数组每一列的元素之和

    int b[4] = {0};

    b[0] += a[0][0]

    for(i = 0;i < 4;i++)//列下标

    {

    for(j = 0;j < 3;j++)//行下标

    {

    b[i] += a[j][i]

    }

    }

    int max = b[0];

    int i_max ;

    for(i = 0;i < 4;i++)

    {

    if(max < b[i])

    {

    max = b[i];

    i_max = i;

    }

    }

    4)求一个二维数组山顶元素的个数,打印出山顶元素是哪个及其它的位置

    判断a[i][j]是否为山顶元素,实际上就是判断比上,下,左,右都大

    1 2 3 5

    4 5 2 4

    1 2 3 5

    2 5 6 3

    :不存在 ,存在 (比它大)

    :不存在 ,存在 (比它大)

    :不存在 ,存在 (比它大)

    :不存在 ,存在 (比它大)

    if(上::不存在 ,存在 (比它大)&&下 :不存在 ,存在 (比它大) && 左 :不存在 ,存在 (比它大)

    && 右 :不存在 ,存在 (比它大))

    {

    }

    =

    int a[4][4]

    if((i==0 || a[i][j] > a[i-1][j]) &&

    (i == 3 || a[i][j]>a[i+1][j]) &&

    (j==0 || a[i][j] > a[i][j-1]) &&

    (j == 3 || a[i][j] > a[i][j+1]))

    {

    printf("a[%d][%d] = %d ",i,j,a[i][j]);

    }

    //第四题,求一个二维数组中山顶元素的个数,也就是比四周的元素都大

    //未知行列

    //第三题,求一个二维数组中列元素之和的最大那个列

    /* int a[3][3];

    int i = 0, j;

    for(i = 0; i < 3; i++)

    for(j = 0; j < 3; j++)

    {

    scanf("%d", &a[i][j]);

    }

    int b[3] = {0};

    for(j = 0; j < 3; j++)

    {

    for(i = 0; i < 3; i++)

    {

    b[j] += a[i][j];

    }

    }

    if(b[0] >= b[1] && b[0] >= b[2])

    {

    printf("1 ");

    }

    if(b[1] >= b[2] && b[1] >= b[0] )

    {

    printf("2 ");

    }

    else

    {

    printf("3 ");

    } */

    //第一题,定义一个整型的二维数组,从键盘上给各个元素赋值,再把整个数组输出

    /*int a[3][3];

    int i = 0, j;

    for(i = 0; i < 3; i++)

    for(j = 0; j < 3; j++)

    {

    scanf("%d", &a[i][j]);

    }

    for(i = 0; i < 3; i++)

    for(j = 0; j < 3; j++)

    {

    printf("%d ", a[i][j]);

    }*/

    //第二题,求一个二维数组的max, min, sum

      /* int a[2][2];

    int i, j, sum = 0, min = 0, max = 0;

    for(i = 0; i < 2; i++)

    for(j = 0; j < 2; j++)

    {

    scanf("%d", &a[i][j]);

    }

    for(i = 0; i < 2; i++)

    for(j = 0; j < 2; j++)

    {

    sum += a[i][j];

    if(a[i][j] <= min)

    {

    min = a[i][j];

    }

    if(a[i][j] >= max)

    {

    max = a[i][j];

    }

    }

    printf("%d,%d, %d ", min, max, sum); */

    作业:

    1打印杨辉三角前10

    1

    1 1

    1 2 1

    1 3 3 1

    1 4 6 4 1

    1 5 10 10 5 1

    2高数巨占座位

    a[6][6];

    n = 3

    0 0 0 1 1 0

    0 0 0 1 1 0

    0 1 0 1 0 1

    0 0 0 0 0 0

    0 1 1 0 1 0

    0 1 0 1 0 0

    求有多少种方式

    3.求一个一维数组最大子数组之和

    子数组:在一个数组中下标连续的n个元素(n>0),称为原数组的子数组

    2 -1 3

    2  =>2

    2 -1 => 1

    2 -1 3  =>4

    -1 =>-1

    -1 3  =>2

    3  =>3

    4.数组部分和

    int a[N];

    K

    能不能从数组a中,任意选M个元素(M > 0,M <= N,使得这M个元素和为K,元素不要求连续

    a:2 5 6 3 1 -1 -2 2

    M = 3 (自己输)

    K = 6 (自己输)

    自己做的

    第一题

    #include<stdio.h>

    int main()

    {

    printf("汉字测试: You know the test begin: ");

    //

    //杨辉三角前10

    // 1

    // 11

    // 121

    // 1331

    // 14641

    int s[10][10] = {{1},{1,1}};

    int i, j;

    for(i = 0; i < 10; i++)

    for(j = 0; j < 10; j++)

    {

                if(j == 0 || i == j)

                {

                    s[i][j] = 1;

                }

                else

                {

                     s[i][j] = s[i-1][j] + s[i-1][j-1];

                }

                printf("%d ", s[i][j]);

                if(i == j)

                {

                    printf(" ");

                    break;

                }

            }

    return 0;

    }

         /*   if(j == 0)//就是首直接设置

            {

                s[i][j] = 1;

                printf("%d ", s[i][j]);

            }

            if(j == i)//就是尾直接设置

            {

                s[i][j] = 1;

                printf("%d ", s[i][j]);

                break;

            }

            //其余位置

            s[i][j] = s[i-1][j] + s[i-1][j-1];

            printf("%d ", s[i][j]);*/

    第二题

    #include<stdio.h>

    int main()

    {

    // 1.高数巨占座位

    // a[6][6];

    // n = 3

    // 0 0 1

    // 1 0 0

    // 1 0 1

    // 0 0 0 1 1 0

    // 0 0 0 1 1 0

    // 0 1 0 1 0 1

    // 0 0 0 0 0 0

    // 0 1 1 0 1 0

    // 0 1 0 1 0 0

    // 求有多少种方式

    printf("汉字测试: You know the test begin: ");

    int i, j, o, p, n, resolution = 0, flag = 0;//op为输入的行列

    scanf("%d%d%d", &o, &p, &n);

    int arg[o][p];

    for(i = 0; i < o; i++)

    for(j = 0; j < p; j++)

    {

    scanf("%d", &arg[i][j]);

    }

    for(i = 0; i < o; i++)

    {

    for(j = 0; j < p; j++)

    {

    if(arg[i][j] == 0)//还需要考虑一种情况,就是碰到1重置

    {

    flag++;

    if(flag == n)

    {

    resolution++;

    //这里更换了位置

    }

    }

    else

    {

    flag = 0;//调换到这里来,才可以处理碰到1重置

    }

    }

    flag = 0;

    }

    printf("这里有这么多种方案:%d ", resolution);

    return 0;

    }

    第三题

    #include<stdio.h>

    #define N 3

    int main()

    {

    // 2.求一个一维数组最大子数组之和

    // 子数组:在一个数组中下标连续的n个元素(n>0),称为原数组的子数组

    // 2 -1 3

    // 2  =>2

    // 2 -1 => 1

    // 2 -1 3  =>4

    // -1 =>-1

    // -1 3  =>2

    // 3  =>3

    int arg[N], i, j , max = 0, sum;

    for(i = 0; i < N; i++)

    {

    scanf("%d", &arg[i]);

    }

    sum = arg[0];

    for(i = 0; i < N; i++)

    {

        max = 0;

    max += arg[i];

    for(j = i + 1; j < N; j++)

    {

    max += arg[j];

    if(max > sum)

    {

    sum = max;

    }

    }

    }

    printf("这个最大的数为:%d ", sum);

    return 0;

    }

    自己第一次做的

    #include<stdio.h>

    int main()

    {

    // 2.求一个一维数组最大子数组之和

    // 子数组:在一个数组中下标连续的n个元素(n>0),称为原数组的子数组

    // 2 -1 3

    // 2  =>2

    // 2 -1 => 1

    // 2 -1 3  =>4

    // -1 =>-1

    // -1 3  =>2

    // 3  =>3

    int m, i, n, flag = 0, max = 0, j = 0;//j用来记录第二个数组的,记录max的大小

    scanf("%d%d", &m, &n);//m是数组长度,nn个元素

    int b[m], arg[m];//b数组用来记录连续子数组的大小

    for(i = 0; i < m; i++)

        {

            b[i] = 0;

        }

    for(i = 0; i < m; i++)//输入数组

    {

    scanf("%d", &arg[i]);

    }

    for(i = 0; i < m; i++) //arg[0]开始往后计数

    {

    max += arg[i]; //累加

    flag++;

    if(flag == n)       //标记n个就重置

    {

    printf("the flag is full ");

    flag = 0;

    b[j++] = max; //连续记录

    max = 0;

    i -= n - 1; //倒退n-1

    }

    }

    max = b[0];

    for(i = 0; i < m ; i++)

    {

            printf("all of the b[i] are:%d ", b[i]);

    if(b[i] >= max)

    {

    printf("the value of b[i] is:b[%d] ", b[i]);

    max = b[i];

    }

    }

    printf("the maximum value is:%d ", max);

    return 0;

    }

    答案

    作业:

    1.高数巨占座位

    a[6][6];

    n = 3

    0 0 0 1 1 0    1

    0 0 0 1 1 0    1

    0 1 0 1 0 1   

    0 0 0 0 0 0    4

    0 1 1 0 1 0    

    0 1 0 1 0 0   

    int count = 0;//表示一行连续 0个数

    int s = 0;//总的占座位的方式

    for(i = 0;i < 6;i++)

    {

    count = 0;

    for(j = 0;j < 6;j++)

    {

    if(a[i][j] == 0)

    {

    count++;//连续为0的个数加1

    if(count >= 3)

    {

    s++;

    }

    }

    else

    {

    count = 0;

    }

    }

    }

    printf("s = %d ",s);

    求有多少种方式

    2.求一个一维数组最大子数组之和

    子数组:在一个数组中下标连续的n个元素(n>0),称为原数组的子数组

    2 -1 3

    2  =>2

    2 -1 => 1

    2 -1 3  =>4

    -1 =>-1

    -1 3  =>2

    3  =>3

    算法1

    所有的子数组

    a1  所有开头的子数组

    a1

    a1+a2

    a1+a2+a3

    j = 0;

    sum = a[0];

    j = 1;

    sum = a[0] +a[1]

    j = 2;

    sum = a[0]+a[1]+a[2]

    max = a[0];

    sum = a[0];

    for(j = 1;j < N;j++)

    {

    sum += a[j];

    if(sum > max)

    {

    max = sum;

    }

    }

    =>

    max = a[0];

    for(i = 0;i < N;i++)//i开头的子数组

    {

    sum = a[i];

    for(j = i+1;j < N;j++)

    {

    sum += a[j];

    if(sum > max)

    {

    max = sum;

    }

    }

    }

    算法2

    + - + - - + +

    sum = 0;

    max = a[0];

    for(i = 0;i < N;i++)

    {

    sum += a[i];

    if(max < sum)

    {

    max = sum;

    }

    if(sum < 0)

    sum = 0;

    }

    3.数组部分和

    int a[N];

    K

    能不能从数组a中,任意选M个元素(M > 0,M <= N,使得这M个元素和为K,元素不要求连续

    a:2 5 6 3 1 -1 -2 2

    M = 3 (自己输)

    K = 6 (自己输)

    2 5 6 3 1 -1 -2 2

    对于数组中的任意一个元素a[i] ,只有两种情况

    选中 1

    不选  0

    0 0 0 0 0 0 0 0 0   不选任意一个数组元素

    1 0 0 0 0 0 0 0 1    选中a[0]

    2 0 0 0 0 0 0 1 0    选中a[1]

    3 0 0 0 0 0 0 1 1    选中a[0] a[1]

    0 0 0 0 0 1 1 1

    .....

    2^n-1 1 1 1 1 1 1 1 1

    (2^n -1)

    0 ~2^n-1

    x [0~2^n-1]

    for(x = 0; x <=(1<<n)-1;x++)

    {

    for(j = 0;j < n;j++)

    {

    if(x & (1 << j))

    {

    //x的第jbit1

    sum += a[j];

    }

    }

    if(sum == k)

    {

    }

    }

  • 相关阅读:
    凤凰网面试经历——钢管舞也算精英文化吗
    立此为证:豆瓣要做电影数字发行了(2010818)
    Officially GoldenGate was purchased by oracle in October 1, 2009
    11gR2新特性:Heavy swapping observed on system in last 5 mins.
    Oracle BMW Racing sailing vessel帆船图
    Know more about CBO Index Cost
    Samsung Epic 4G 图文介绍
    Oracle Exalogic X22 HalfRack DiagramExaloic半配图
    Java 编程下线程的生命周期
    Android 编程组件Fragments 的生命周期与 Activity 的生命周期之间的关系
  • 原文地址:https://www.cnblogs.com/qihuanye-229110/p/11147329.html
Copyright © 2011-2022 走看看