本次作业你将熟悉 Java 的基本类型 (primitive type), 表达式 (expression) 和控制结构 (control flow). 这些“面向过程”的方法是实现“面向对象”编程的基础. 另一方面, 你将复习模块化编程 (modular programming): 练习如何定义, 使用静态函数, 使用静态类编写一个简单的库. 希望此次作业能够帮助你了解 Java 的基础语法, 特别是它与 C 语言的区别. 同时, 希望通过强调“模块化”的概念, 为今后学习面向对象的设计打下基础.
Java 为一些基本类型提供了封装 (Wrapper). 通过封装, Java 可以提供更丰富的面向的基本类型操作. 以下我们以整型为例说明如何使用这些基本类型的封装. 考虑一个32位整型变量
用户可以对 a 进行加法, 乘法等运算. 但对一些较复杂的操作, 仍需要自行实现. 例如, 给定一个由数字组成的字符串 (“12235”), 将其转换成对应的整数 (问题: C 语言这个功能是如何实现?). 为了更方便用户使用, Java 将整型封装成为 Integer 类, 并在其中提供了一些针对整型的复杂操作. 例如, 为了将字符串转换成为整型, Integer 类提供了静态方法 parseInt():
又如, Integer 类提供了方法 toBinaryString(), 返回整形变量的二进制表示字符串:
事实上, 除了使用 Integer 类的静态方法外, 我们也可以使用 Integer 类的对象:
Integer a = new Integer(11235);
. 在作为函数参数时, 或者在赋值表达式中, Integer 对象和 int 可以通用. 例如对于上面的 Integer 对象 a, 我们可以将其赋值给 int 型变量 bint b = a;
, 反之亦然. Java 编译器提供了这些情况下 int 到 Integer 对象的自动转换 (称为 autoboxing), 以及 Integer 对象到 int 的转换 (称为 unboxing). 关于 autoboxing 和 unboxing 可以参考这里.
关于 Integer 类的详细文档在这里. 除了整型外, 对于一些其他基本类型也有类似的封装: Boolean, Byte, Character, Double, Float, Long, Short.
我们可以使用 Math 包中的 random 方法产生 0 到1 间的随机数:
例如, 以下代码将以概率 p 输出1, 以概率 1-p 输出0:
Random 类 也提供了产生随机数的接口.
##实验内容
以下表达式是否能够通过编译? 如果能够通过, 表达式的类型是什么? 表达式的值是什么? 请尝试解释原因.
假设int a = 2147483647;
(即, Integer.MAX_VALUE
). 请问以下语句的输出值是什么? 并解释原因.
函数Math.sqrt(double t)
计算一个数的平方根. 表达式Math.sqrt(2)*Math.sqrt(2) == 2
的值是什么?
给定命令行参数 x1, y1, x2, y2. 计算平面上的点 (x1, y1) 和 (x2, y2) 的距离.
计算函数 logx,x,xlogx,x2,x3 在 x=1,2,4,8,16,...,2048 处的值. 并比较它们的增长速度.
使用牛顿法计算平方根. 对于可导函数 f(x), 牛顿法用于计算 f 的零点 (f(x)=0). 令 f(x) 在 t 的导数为 f′(t). 给定初始值 x0, 首先计算过点 (x0,f(x0)), 斜率为 f′(x0) 的直线与x轴的交点, 令该点为 x1. 对 x1, 计算过点 (x1,f(x1)), 斜率为f′(x1)的直线与x轴的焦点, 令其为x2. 重复以上过程直到得到点 xn 使得 f(xn)=0 (过程参见1). 计算 √c 等价于找函数 f(x)=x2−c 的零点.
给定5个整数 (通过命令行参数), 找出它们的中位数 (即第3大的数).
Hadamard 矩阵 H(N) 为 2N−1×2N−1 的方阵. 矩阵中的元素为 0 或者 1. H(1)=[1], H(N)=[H(N−1)H(N−1)H(N−1)¬H(N−1)] 其中 ¬H(N−1) 表示将H(N−1)中的0变成1, 1变成0. 例如: H(2)=[1110],H(3)=[1111101011001001] 给定 N, 请输出 H(N).
Alice 去参加一个聚会. Bob 也在这个聚会中. 看到 Alice 之后, Bob 把一个和 Alice 有关的八卦谣言告诉了他的一个同伴. 随后谣言开始在聚会中传播. 假设人们都按照以下方式传递谣言: 如果他第一次听到, 则从其他的人中随机选择一个 (除了告诉他的那个人和Alice), 将谣言传递出去. 如果他已经知道了这个谣言, 那么他停止传播. 请通过模拟来估计在谣言传播停止前, 所有人(除了 Alice)都知道这个谣言的概率. 同时, 请估计听到谣言人数的期望值.
给定整数 N , 输出 1 到 N 的所有排列. 利用本题测试第8题中寻找中位数的算法是否正确.
任何 1 到 N 的排列可以定义一个 {1,2,...,N} 到自身的函数 (称为一个 N 阶置换). 例如, 令排列 (2,5,4,3,1) 对应的置换为 σ, 则它的取值为 σ(1)=2, σ(2)=5, σ(3)=4, σ(4)=3, σ(5)=1. 置换 σ,τ 的积定义为它们的函数复合 τ∘σ (即, τ∘σ(i)=τ(σ(i)), ∀i). 显然τ∘σ同样为一个置换. 例如若 τ=(2,1,4,5,3),σ=(2,5,4,3,1), 则 τ∘σ 的取值为 τ∘σ(1)=τ(σ(1))=τ(2)=1τ∘σ(2)=τ(σ(2))=τ(5)=3τ∘σ(3)=τ(σ(3))=τ(4)=5τ∘σ(4)=τ(σ(4))=τ(3)=4τ∘σ(5)=τ(σ(5))=τ(1)=2 因此 τ∘σ=(1,3,5,4,2). 定义衡等置换e=(1,2,..N) (即, e(i)=i, ∀i). 定义置换 σ 的逆 σ−1 满足 σ∘σ−1=σ−1∘σ=e. 给定一个置换, 输出它的逆. 要求除了存储置换的数组外不能使用其他的数组.
8 皇后问题. 我们可以用排列代表国际象棋棋盘上皇后的位置. 例如排列 (5,2,4,1,3) 可以代表如下棋盘的布局
* * * Q *
* Q * * *
* * * * Q
* * Q * *
Q * * * *
其中, 每一个Q代表一个皇后, 星号表示空白棋格. 给定排列, 输出其代表的棋盘是否是一个“安全”的棋盘, 要求除了存储排列的数组外, 不能使用其他的数组. 国际象棋规则中, 一个皇后可以 “吃掉” 任何和它处于同一直线上的棋子(即同列, 同行, 同对角线, 同反对角线). 例如, 以下棋盘中A, B, C, D位置的棋子都可以被皇后吃掉, 类似的位置被称为“不安全位置”.
* * B * *
* A * * *
* * Q * C
* * * * *
D * * * *
一个“安全”的棋盘为棋盘中所有皇后都处在安全位置 (不会被其他的皇后吃掉.)
编写库文件 Statistic.java, 包含如下静态方法:
方法 \ | 说明 |
---|---|
double max(double a[]) | 返回数组a中的最大值 |
double min(double a[]) | 返回数组a中的最小值 |
double mean(double a[]) | 返回数组a的均值 |
double variance(double a[]) | 返回数组a的方差 |
double select(double a[], k) | 返回数组a中第k大的数 |
double []histogram(double a[]) | 返回数组b, b[i]表示a[i]在a中出现的次数 |
假定数据文件的格式为每行一个[0, 1]间的数字. 编写程序Compute.java, 从命令行获得数据文件的名称, 输出该文件中数字的最大值, 均值, 方差, 中位数. 同时输出出现次数最多的数, 最靠近均值的数, 与均值的距离小于1倍方差, 2倍方差, 3倍方差的数.