public static int BinarySearch(int key, int[] a) {
int lo = 0;
int hi = a.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (key < a[mid]) hi = mid - 1;
else if (key > a[mid]) lo = mid + 1;
else return mid;
}
return -1;
}
---------------------
//初始化
public static int rankSearch(int key, int[] a) {
return rank(key, a, 0, a.length - 1);
}
public static int rankSearch(int key, int[] a, int lo, int hi) {
if(lo > hi) return -1;
int mid = lo + (hi - lo) / 2;
if(key < a[mid]) return rank(key, a, lo, mid -1);
else if(key > a[mid]) return rank(key, a, mid + 1, hi);
else return mid;
}
rank(key,int[] a) 返回数组中小于key的元素的数量
count(key,int[] a) 返回数组中等于key的元素的数量
/**
* @param key
* @param a 返回小于key的元素的数量
*/
public static int rank(int key, int[] a) {
int lo = 0;
int hi = a.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (key < a[mid]) hi = mid - 1;
else if (key > a[mid]) lo = mid + 1;
else {
while (a[mid] == a[mid - 1] && mid > 0) {
mid--;
}
return mid;
}
}
return -1;
}
public static int count(int key,int[]a ) {
int cnt = 0;
int i = rank(key, a);
while (a[i] == a[i + 1] && i < a.length) {
cnt++;
i++;
}
return cnt;
}
-
2.0e-6 * 100000000.1
- 2.0e-6 是一个科学计数法,表示 0.000002
- 0.000002 * 100000000.1 = 200.0000002
int sum = 0;
for (int i = 1; i < 1000; i++) {
for (int j = 0; j < i; j++) {
sum++;
}
}
System.out.println(sum);
注意i,j值的范围
System.out.println('b');
System.out.println('b' + 'c');
System.out.println((char) ('a' + 4));
b
197
e
-
除2取余循环商,逆序排列法:用2整除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商为0时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。
-
算法分析
- 字符串相加时可以通过加号顺序实现逆序排列
- n = n/2实现取商
- n % 2 实现取余
Scanner in = new Scanner(System.in);
int N = in.nextInt();
String s = "";
for (int n = N; n > 0; n /= 2) {
s = (n % 2) + s;
}
考虑输出的值
int[] a = new int[10];
for(int i = 0;i<10;i++) {
a[i] = 9 - i;
}
for (int i = 0; i < 10; i++) {
a[i] = a[a[i]];
}
for (int i = 0; i < 10; i++) {
System.out.println(a[i]);
}
public static int lo(int N) {
int x = -1;
int product = 1;
while (product <= N) {
product *= 2;
x++;
}
return x;
}
待优化的方法:
public static long F(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
return F(n - 1) + F(n - 2);
}
不使用递归会提高效率
public static long F(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
long f = 0;
long g = 1;
for(int i = 0;i<n;i++) {
f = f + g;
g = g + f;
}
return f;
}
public static int[] deleteRepeat(int[] a) {
int[] b = new int[a.length];
int s = 0;
b[0] = a[0];
for (int i = 0; i < a.length - 1; i++) {
if (a[i] == a[i + 1]) {
s++;
} else {
b[i - s + 1] = a[i + 1];
}
}
//优化数组,删除后面空的地址
int[] result = new int[b.length - s];
for (int i = 0; i < b.length - s; i++) {
result[i] = b[i];
}
return result;
}
- 递归算法
public static int gcd(int m, int n) {
if (m == 0 || n == 0) return 1;
if (m % n == 0) return n;
else return gcd(n, m % n);
}
public static void drawRandConn(int N, double p) {
//这里应该添加一个对p的检查
//设置画布大小
StdDraw.setCanvasSize(1024, 1024);
//设置相对坐标
StdDraw.setScale(-1.0, 1.0);
StdDraw.setPenRadius(.015);
double[][] d = new double[N][2];
//通过改变α角 来控制点的位置
for (int i = 0; i < N; i++) {
//x = r.cos α , y = r.sin α
d[i][0] = Math.cos(2 * Math.PI * i / N);
d[i][1] = Math.sin(2 * Math.PI * i / N);
StdDraw.point(d[i][0], d[i][1]);
}
StdDraw.setPenRadius();
//N个点,遍历N-1次,最后一个点在前面遍历时已经被用了
for (int i = 0; i < N - 1; i++) {
//j = i+1 从当前点(i)的下一个点开始遍历
for (int j = i + 1; j < N; j++) {
//根据概率返回一个随机boolean
if (Math.random() < p) {
StdDraw.line(d[i][0], d[i][1], d[j][0], d[j][1]);
}
}
}
}
- 分别写两个方法,一个是理想情况,一个是模拟投掷
StdRandom.uniform(1, 7)
public static double[] getExact() {
int SIDES = 6;
//下标表示两次骰子之和,值表示概率
double[] dist = new double[2 * SIDES + 1];
//对两次骰子之和遍历,每遍历到一个和这个和的计数器加1
for (int i = 1; i <= SIDES; i++) {
for (int j = 1; j <= SIDES; j++) {
dist[i + j] += 1.0;
}
}
//之所以不用遍历是因为dist[0] 和 dist[1]的值都是0,除法运算无意义
for (int i = 2; i <= 2 * SIDES; i++) {
//一共36种情况
dist[i] /= 36.0;
}
return dist;
}
public static double[] getExperience(int throwNum) {
int SIDES = 6;
double[] dist = new double[2 * SIDES + 1];
//对投掷次数进行遍历,模拟每一次投掷
for (int i = 0; i < throwNum; i++) {
int x = StdRandom.uniform(1, 7) + StdRandom.uniform(1, 7);
dist[x] += 1.0;
}
for (int i = 0; i < SIDES * 2; i++) {
dist[i] /= throwNum;
}
return dist;
}
public static String cut(String t, String p) {
boolean succ = false;
int j;
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= t.length() - p.length(); i++) {
j = 0;
succ = false;
while (j < p.length()) {
if (t.charAt(i + j) != p.charAt(j)) {
succ = false;
break;
} else {
j++;
succ = true;
}
}
if (!succ) {
sb.append(t.charAt(i));
} else {
sb.append('\n');
i += p.length()-1;
}
}
return sb.toString();
}