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\n",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);

 

“字符串長度” :就是從一個起始地址的內容開始找,找到第一個\0為止

前面有多少個字符,那就是字符串的長度

 

數組的長度 :數組有多少個元素

 

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\n",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\n");

}

*/

if(flag)

{

printf("yes\n");

}

 

(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("\n");
printf("%4d",a[i]);



}
printf("\nseach 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",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.字符數組

元素都是字符形式

 

字符串的結束標志 '\0'

 

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

 

%s :格式符 輸出字符串

 遇到第一個\0結束

 

printf("%s\n",s);

 

 

字符串的操作函數:

strlen :求字符串的長度,

遇到第一個\0結束

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\n",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\n");

}

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

{

printf("2\n");

}

else

{

printf("3\n");

} */

 

 

//第一題,定義一個整型的二維數組,從鍵盤上給各個元素賦值,再把整個數組輸出

/*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\n", 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\n", 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("漢字測試:\t You know the test begin:\n");

//

 

//楊輝三角前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\t", s[i][j]);

 

            if(i == j)

            {

                printf("\n");

                break;

            }

        }

return 0;

}

 

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

        {

            s[i][j] = 1;

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

        }

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

        {

            s[i][j] = 1;

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

            break;

        }

        //其余位置

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

        printf("%d\t", 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("漢字測試:\t You know the test begin:\n");

 

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\n", 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\n", 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\n");

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\n", b[i]);

if(b[i] >= max)

{

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

max = b[i];

}

}

 

printf("the maximum value is:%d\n", 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\n",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)

{

 

}

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM