算法(03):数组

本文介绍了数组这一基本数据结构及其在算法中的应用,包括素数筛选和模拟柏努利实验序列两个实例,展示了数组作为高效索引工具的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  最基本的数据结构应该就是数组了,之所以把数组看成最基本的数据结构,原因在于它与计算机的真实内存直接通信。如果我们要读取机器内存中的字的内容,我们必须提供一个地址。因此我们可以把机器的内存看成是一个数组,内存地址就是数组的下标。而且大多数计算机处理器都把程序中的数组翻译成能直接访问内存的高效代码,我们不必关心其具体细节。

  因此,数组是我们开发有效算法的基础。

  数组是相同的数据类型的固定集合,它是连续存储的,通过下标来访问数组元素。通常a[i]表示数组a中的第i个元素。

  关于数组在某特定语言中的用法请参考相关语言的帮助文档,这里不再赘述。

  我们直接来看看一个使用数组的简单例子:求解小于给定数的所有素数,我们使用公元前三世纪的“埃拉托色尼塞”方法。

 

class Primes{
 
public static void main(String[] args){
  
int N=Integer.parseInt(args[0]);
  
boolean[] a=new boolean[N];
  
for(int i=2;i<N;i++)a[i]=true;
  
for(int i=2;i<N;i++)
   
if(a[i])
    
for(int j=i;j*i<N;j++)
     a[i
*j]=false;
  
for(int i=2;i<N;i++)
   
if(a[i])
    System.out.print(
" "+i);
  System.out.println();
 }

}

 

  在这个算法中,我们利用一个布尔型数组,如果i是素数,就把a[i]设为true,否则,就把a[i]设为false。首先,我们把数组中的所有元素都设为素数。然后再把对应于下标为非素数(是已知素数的倍数)的数组元素设为false。如果在所有较小的素数的倍数都被设为false后,a[i]的值仍然为true,那么它就是素数。

  下面我们再来看一个关于数组的算法。

  这是一个模拟了柏努利实验序列(概率论中经典的结论)。如果我们抛硬币N次,那么出现k次正面的概率为:

Bernoulli

  这是关于柏努利分布的正态逼近(有关知识请参考概率论),这是一种我们熟悉的钟形曲线。

 

class CoinFlip{
 
static boolean heads(){
  
return Math.random()<0.5;
 }

 
public static void main(String[] args){
  
int i,j,cnt;
  
int N=Integer.parseInt(args[0]);
  
int M=Integer.parseInt(args[1]);
  
int[] f=new int[N+1];
  
for(j=0;j<=N;j++)f[j]=0;
  
for(i=0;i<M;i++,f[cnt]++)
   
for(cnt=0,j=0;j<=N;j++)
    
if(heads())cnt++;
  
for(j=0;j<=N;j++){
   
if(f[j]==0)System.out.print(".");
   
for(i=0;i<f[j];i+=10)
    System.out.print(
"*");
   System.out.println();
  }

 }

}

 

  如果我们抛N次硬币,我们会期望出现N/2次正面,但实际上得到的正面次数在0~N之间。我们使用数组f来跟踪结果"i次正面"发生的频率,然后打出实验结果的柱状图,一个*表示每10次发生。程序基于的操作——用计算过的值来索引数组——是很多计算过程效率的关键。具有支持这种类型操作的能力是数组的优点之一。

  实验结果如下图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值