tonglin0325的个人主页

Java排序算法——插入排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import java.util.Arrays;

class Arrays_Insert{
private int[] arrays;
private int curNum;

public Arrays_Insert(int max) { //建立一个max长度的空数组
super();
arrays = new int[max];
curNum = 0;
}

public void insert(int value){ //往空的数组里面增加元素
arrays[curNum] = value;
curNum++;
}

public void display(){ //显示数组
System.out.println(Arrays.toString(arrays));
}

private void swap(int one,int two){ //交换
int temp = arrays[one];
arrays[one] = arrays[two];
arrays[two] = temp;
}

public void InsertSort(){
int out,in;

for(out=1;out<curNum;out++){ //从第2个开始,和第1个比较
int temp = arrays[out];
in = out;                        //in等于out,比较从in-1开始
while(in>0 &amp;&amp; arrays[in-1] >= temp){ //如果大于temp,就往右移动
arrays[in] = arrays[in-1];        例如:2 3 1 temp=1 -> 2 3 3 temp=1 -> 2 2 3 temp=1 -> 1 2 3 temp=1
--in;
}
arrays[in] = temp;
}
}

}

public class Insert_Sort {

public static void main(String[] args) {
// TODO 自动生成的方法存根
int maxSize = 100;
Arrays_Insert arrays_demo = new Arrays_Insert(maxSize);
arrays_demo.insert(58);
arrays_demo.insert(57);
arrays_demo.insert(56);
arrays_demo.insert(60);
arrays_demo.insert(59);
arrays_demo.display();
arrays_demo.InsertSort();
arrays_demo.display();
}

}

 

冒泡    N^2/2比较  N^2/4交换

选择    N^2/2比较  比冒泡少的交换

插入    N^2/4比较  N^2/4复制

复制是交换的3倍

Java数据结构——优先级队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
class PriorityQueue{
private int maxSize; //队列的长度
private long[] queueArray; //创建队列的数组的引用
private int curNum; //创建当前元素的个数

public PriorityQueue(int s) { //构造函数
this.maxSize = s;
queueArray = new long[maxSize]; //创建对象
curNum = 0; //当前的元素的个数是0
}

public void insert(long item){
int j;
if(curNum == 0){ //输入1个数,就是1个数
queueArray[curNum++] = item;
}else{ //左边是rear,右边是front,左边总比右边大
for(j=curNum-1;j>=0;j--){ //当有2个数时,若第2个数比第1个数大,则交换
if(item>queueArray[j]){ //j在-1的时候停止,rear=0,front=curNum-1
queueArray[j+1] = queueArray[j]; // 1 2 -> 1 1 -> 2 1
}else{break;} // 2 1 3 -> 2 1 1 -> 2 2 1 -> 3 2 1
}
queueArray[j+1] = item;
curNum++;
}

}

public long remove(){
return queueArray[--curNum];
}

public long peekFront(){
return queueArray[curNum-1];
}

public boolean isEmpty(){
return (curNum==0);
}

public boolean isFull(){
return (curNum==maxSize);
}


}

public class PriorityQueue_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
PriorityQueue queue_demo = new PriorityQueue(5);
queue_demo.insert(30);
queue_demo.insert(10);
queue_demo.insert(50);
queue_demo.insert(40);
queue_demo.insert(20);
while( !queue_demo.isEmpty()){
long value = queue_demo.remove();
System.out.println(value+"、");
}
}

}

 

Java数据结构——栈

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Stack{
private int maxSize; //栈的长度
private long[] stackArray; //创建栈的数组的引用
private int top; //创建栈顶的引用

public Stack(int s) { //构造函数
this.maxSize = s;
stackArray = new long[maxSize]; //创建对象
top = -1; //栈顶等于-1
}

public void push(long j){ //入栈操作
stackArray[++top] = j; //先把top=-1自加成0,再入栈
}

public long pop(){
return stackArray[top--]; //弹出当前栈顶的元素后,再自减
}

public long peek(){
return stackArray[top]; //返回当前栈顶的元素
}

public boolean isEmpty(){ //栈顶为-1,即栈为空
return (top == -1);
}

public boolean isFull(){ //栈顶为maxSize-1,即栈为满
return (top == maxSize-1);
}

}

public class Stack_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
Stack stack_demo = new Stack(10);
stack_demo.push(50);
stack_demo.push(60);
stack_demo.push(70);
stack_demo.push(80);

while(!stack_demo.isEmpty()){ //当栈不为空
long value = stack_demo.pop();
System.out.print(value+"、");
}
}

}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class Stack_Char{
private int maxSize; //栈的长度
private char[] stackArray; //创建栈的数组的引用
private int top; //创建栈顶的引用

public Stack_Char(int s) { //构造函数
this.maxSize = s;
stackArray = new char[maxSize]; //创建对象
top = -1; //栈顶等于-1
}

public void push(char j){ //入栈操作
stackArray[++top] = j; //先把top=-1自加成0,再入栈
}

public char pop(){
return stackArray[top--]; //弹出当前栈顶的元素后,再自减
}

public char peek(){
return stackArray[top]; //返回当前栈顶的元素
}

public boolean isEmpty(){ //栈顶为-1,即栈为空
return (top == -1);
}

public boolean isFull(){ //栈顶为maxSize-1,即栈为满
return (top == maxSize-1);
}

}

class Reverse{
private String input;
private String output;

public Reverse(String input) { //构造函数
super();
this.input = input;
}

public String DoReverse(){
int stackSize = input.length();
Stack_Char stack_demo = new Stack_Char(stackSize);

for(int i=0;i<stackSize;i++){ //把每一个字母入栈
char ch = input.charAt(i);
stack_demo.push(ch);
}
output = ""; //给output赋值,否则会变成nullXXX
while( !stack_demo.isEmpty() ){ //把每一个字母出栈
char ch = stack_demo.pop();
this.output += ch;
}
return this.output;
}

}

public class Word_Reverse {

public static void main(String[] args) {
// TODO 自动生成的方法存根
String input,output;
input = "part";
System.out.println("输入的字符串:"+input);
Reverse rev = new Reverse(input);
output = rev.DoReverse();
System.out.println("输出的字符串:"+output);
}

}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class BracketsChecker{
private String input;

public BracketsChecker(String input) { //构造函数
super();
this.input = input;
}

public void Check(){
int stackSize = input.length();
Stack_Char stack_demo = new Stack_Char(stackSize);

for(int i=0;i<input.length();i++){
char ch = input.charAt(i); //遍历每一个字符
switch(ch){
case '{':
case '[':
case '(':
stack_demo.push(ch); //遇到'{[('就入栈
break;

case '}':
case ']':
case ')':
if( !stack_demo.isEmpty()){
char chx = stack_demo.pop(); //遇到'}])'弹出堆栈
if( (chx=='{' &amp;&amp; ch!='}') || (chx=='[' &amp;&amp; ch!=']') || (chx=='(' &amp;&amp; ch!=')')){
System.out.println("Error:右括号不应该是"+ch+" at "+i);
}
}
else{
System.out.println("Error:只有右括号"+ch+" at "+i);
}
break;
default:break;
}
}
if( !stack_demo.isEmpty()){ //如果栈不为空的话,证明缺少右括号
System.out.println("Error:缺少右括号");
}
}
}

public class Brackets_demo {

public static void main(String[] args) throws Exception{
// TODO 自动生成的方法存根
String input;
// input = "{[(]}";
System.out.print("输入字符串:");
input = getString();
System.out.println("输入的字符串为:"+input);
BracketsChecker che = new BracketsChecker(input);
che.Check();
}

public static String getString() throws IOException{
InputStreamReader isr = new InputStreamReader(System.in); //把输入的字节流转换成字符流
BufferedReader br = new BufferedReader(isr); //只能接收字符输入流的实例
String str = br.readLine(); //一次性从缓冲区中读取内容
return str;
}

}

 

Java数据结构——队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class Queue{
private int maxSize; //队列的长度
private long[] queueArray; //创建队列的数组的引用
private int front; //创建队头的引用
private int rear; //创建队尾的引用
private int curNum; //创建当前元素的个数

public Queue(int s) { //构造函数
this.maxSize = s;
queueArray = new long[maxSize]; //创建对象
front = 0; //队头等于0
rear = -1; //队尾等于-1
curNum = 0; //当前的元素的个数是0
}

public void insert(long j){
if(rear == maxSize-1){ //如果队尾是队列的最大值-1,则队尾等于-1
rear = -1;
}
queueArray[++rear] = j; //先自加为0,然后给队尾的元素赋值
curNum++; //当前的元素的个数加1
}

public long remove(){
long temp = queueArray[front++]; //取得队头的元素,然后自加
if(front == maxSize){
front =0;
}
curNum--; //当前的元素的个数减1
return temp;
}

public long peekFront(){
return queueArray[front];
}

public boolean isEmpty(){
return (curNum==0);
}

public boolean isFull(){
return (curNum==maxSize);
}

public int Size(){ //返回当前队列元素的个数
return curNum;
}

}

public class Queue_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
Queue queue_demo = new Queue(5);
queue_demo.insert(50);
queue_demo.insert(60);
queue_demo.insert(70);
queue_demo.insert(80);
queue_demo.remove();
queue_demo.insert(50);

while( !queue_demo.isEmpty()){
long value = queue_demo.remove();
System.out.print(value+"、");
}
}
}

 

Java排序算法——冒泡排序

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.interview.sort;

import java.util.Arrays;

class ArraysBubble {
private int[] arrays;
private int curNum;

public ArraysBubble(int max) { //建立一个max长度的空数组
super();
arrays = new int[max];
curNum = 0;
}

public void insert(int value) { //往空的数组里面增加元素
arrays[curNum] = value;
curNum++;
}

public void display() { //显示数组
System.out.println(Arrays.toString(arrays));
}

private void swap(int one, int two) { //交换
int temp = arrays[one];
arrays[one] = arrays[two];
arrays[two] = temp;
}

public void BubbleSort() {
for (int i = 0; i < curNum; i++) {
for (int j = i + 1; j < curNum; j++) {
if (arrays[j] < arrays[i]) {
swap(i, j);
}
}
}
}

// public void BubbleSort() {
// int out, in;
// for (out = curNum - 1; out > 0; out--) { //curNum自加为下一次插入做做准备,在此应减去1
// for (in = 0; in < out; in++) { //从最后一个数开始,和前面每一个数比较,把最大的移到最后
// if (arrays[in] > arrays[out]) {
// swap(in, in + 1);
// }
// }
// }
//
//
// }
}

public class BubbleSort {

public static void main(String[] args) {
// TODO 自动生成的方法存根
int maxSize = 100;
ArraysBubble arrays_demo = new ArraysBubble(maxSize);
arrays_demo.insert(58);
arrays_demo.insert(57);
arrays_demo.insert(56);
arrays_demo.insert(60);
arrays_demo.insert(59);
arrays_demo.display();
arrays_demo.BubbleSort();
arrays_demo.display();
}

}

 输出

1
2
3
[58, 57, 56, 60, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[56, 57, 58, 59, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

 

Java排序算法——选择排序

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import java.util.Arrays;

class Arrays_Select{
private int[] arrays;
private int curNum;

public Arrays_Select(int max) { //建立一个max长度的空数组
super();
arrays = new int[max];
curNum = 0;
}

public void insert(int value){ //往空的数组里面增加元素
arrays[curNum] = value;
curNum++;
}

public void display(){ //显示数组
System.out.println(Arrays.toString(arrays));
}

private void swap(int one,int two){ //交换
int temp = arrays[one];
arrays[one] = arrays[two];
arrays[two] = temp;
}

public void SelectSort(){
int out,in,min;

for(out=0;out<curNum-1;out++){
min = out; //out从0开始,设第一个为最小
for(in=out+1;in<curNum;in++){           //搜索之后的元素,从1开始,如果有比第0个小,交换
if(arrays[in]<arrays[min]){       //都是找到未排序中最小的数
min = in; //找到最小数的标号
}
swap(out,min); //交换
}
}
}
}

public class Select_Sort {

public static void main(String[] args) {
// TODO 自动生成的方法存根
int maxSize = 100;
Arrays_Select arrays_demo = new Arrays_Select(maxSize);
arrays_demo.insert(58);
arrays_demo.insert(57);
arrays_demo.insert(56);
arrays_demo.insert(60);
arrays_demo.insert(59);
arrays_demo.display();
arrays_demo.SelectSort();
arrays_demo.display();
}

}

 

Java查找算法——二分查找

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import java.lang.reflect.Array;
import java.nio.Buffer;
import java.util.Arrays;
import java.util.Random;

class BinarySearch_Find{
private int[] temp;
private int searchKey;
private int lowerBound = 0; //下界
private int upperBound ; //上界
private int curNum;

public int[] getTemp() {
return temp;
}

public void setTemp(int[] temp) {
this.temp = temp;
}

public BinarySearch_Find(int[] temp) {//构造函数
this.temp = temp;
this.upperBound = temp.length-1;
}

public int find(int searchKey){
this.searchKey = searchKey;
while(true){
curNum = (lowerBound+upperBound)/2;
if(temp[curNum]==this.searchKey){
return curNum; //find
}
else if(lowerBound>upperBound){
return -1; //没有find
}
else{
if(temp[curNum]<this.searchKey){
lowerBound = curNum+1;
}
else{
upperBound = curNum-1;
}
}
}
}

}

class RandomArrays{ //生成随机数组,有Num个

public int[] getArrays(int Num){
int[] Arrays = new int[Num];
Random r = new Random();

for(int i=0;i<Num;i++){
Arrays[i] = r.nextInt(1000);
// System.out.print(Arrays[i]+"、");
}
return Arrays;
}
}

class OrderedArrays{ //生成有序数组,从0开始到Num

public int[] getArrays(int Num){
int[] Arrays = new int[Num];

for(int i=0;i<Num;i++){
Arrays[i] = i;
// System.out.print(Arrays[i]+"、");
}
return Arrays;
}
}

public class Binary_Search {

public static void main(String[] args) {
// TODO 自动生成的方法存根

// RandomArrays array_demo = new RandomArrays();
// BinarySearch_Find arrays = new BinarySearch_Find(array_demo.getArrays(100));

OrderedArrays array_demo = new OrderedArrays();
BinarySearch_Find arrays = new BinarySearch_Find(array_demo.getArrays(100));
System.out.println(Arrays.toString(arrays.getTemp()));
System.out.println(arrays.find(1000));

}
}

 

SpringBoot学习笔记——filter和interceptor

Servlet API中提供了一个Filter接口,Filter接口在javax.servlet.Filter包下面。开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter

通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:

WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。

例如实现URL级别的权限访问控制、乱码问题过滤敏感词汇压缩响应信息等一些高级功能。

filter在开发中的常见应用:
        1.filter可以目标资源执行之前,进行权限检查,检查用户有无权限,如有权限则放行,如没有,则拒绝访问
        2.filter可以放行之前,对request和response进行预处理,从而实现一些全局性的设置。
        3.filter在放行之后,可以捕获到目标资源的输出,从而对输出作出类似于压缩这样的设置 

在filter中可以对request请求进行拦截,并对response进行修改

全文 >>

广告系统当中的ID

在广告系统当中,ID是标识用户比较重要的手段,

1.安卓端#

AdID:又称为Google advertising ID,海外安卓平台常用的设备标识符,每一台 Android设备都会被分配一个唯一的标识符,海外安卓平台的广告投放归因也主要依赖AdID。在国内,因google play在大陆地区无法使用,故google推动的adid也无法使用。且在android12开始,所有在设备设置中选择退出个性化广告的用户,其广告 ID 会变为一串零 (0),这将会影响android广告的归因。参考:移动广告流量中那些ID的坑Google 宣布移除限制广告跟踪用户的安卓广告 ID

IMEI(International Mobile EquipmentIdentity,移动设备国际识别码,又称为国际移动设备标识),即手机的卡槽号ID,可见这种ID是用户无法关闭或重置的,严格意义上来说在个人信息隐私保护方面存在不合规的高风险,所以采集时要经过用户的授权同意,存储使用时也一定要进行加密处理(MD5摘要加密),匿名化处理。也正是IMEI对个人信息隐私保护方面存在不合规性的高风险,所以从Android Q 开始,IMEI等ID的获取将受到非常大的安全限制,需用户每次授权。故国产手机纷纷开始推广OAID体系。参考:穿山甲——如何获取设备ID

OAID:OAID全称是Open Anonymous Device Identifier,中文名是匿名设备标识符。 OAID是一种非永久性设备标识符,最长64位,在系统首次启动的时候生成。 因此OAID可在保护用户个人数据隐私安全的前提下,用于向用户提供个性化广告,用户统计,同时三方监测平台也可以向广告主提供转化归因分析。支持OAID的条件:1)安卓设备系统版本10及以上; 2)设备品牌:HUAWEI/OPPO/VIVO/XIAOMI

ANID:ANDROID_ID android设备的唯一识别码,在设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来,这个16进制的字符串就是ANDROID_ID,当设备被wipe后该值会被重置。

2.IOS端#

IDFA:IOS系统下的广告流量主ID相对于Android的情况要好很多了,基本统一使用IDFA(Identifier For Advertising)