算法笔记

一、格式类

1.格式显示

  • printf("%.nf",浮点数)保留小数n位
  • printf("%nd",整数) 控制数字至少占n位(默认右对齐)
  • printf("%-nd",整数)控制数字至少占n位,左对齐
  • printf("%+nd",整数)控制数字至少占n位,显示+号
  • printf("%±nd",整数)控制数字至少占n位,左对齐,显示+号

2.进制转换

  • 转10进制为任意进制
    • String s=Integer.toString(a,16) //a为int型,16表示转为16进制
  • 将任意进制的转换为10进制 (注意下面Long的L 为大写)
    • int b= Integer.valueOf(a,16);//16表示将16进制的a转换为10进制(a的类型为字符串)

3.大数:

  • BigInteger a=new BigInteger(“100000000000000000”)

4.整形比较注意事项

  • 不能用两个Integer类型的值进行比较,可转为int型比较

二、数学类

1.取余和取模(符号区别):

  • a对b取余数 的话:结果的正负号只和a相同
  • a对b取模的话:结果的正负号只和b相同

2.浮点数比较:

a==b转化为Math.abs(a-b)<1E-6

3.求一个数的各个位的数:

  • n/(1,10,100…)%10

4.最大公约数&最小公倍数

  • 最大公约数:

    	public static int max(int a,int b){
    		if(b%a==0)return a;
    		return max(b%a,a);
    	}
    

5. 产生a——b的随机数

	```
	(int)(Math.random()*(b-a+1))+a
	```

5.保留小数

保留几位小数:
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
//四舍五入
nf.setRoundingMode(RoundingMode.UP); (//不需要四舍五入;:nf.setRoundingMode(RoundingMode.DOWN);)
nf.format(1.555555);

  • 最小公倍数=(min(a,b)/最大公约数)*max(a,b)

5.博弈论

  • 每次执行方法都是一个新的局面,当前局面要想赢,上个局面必须输。

四舍五入

  • Math.round();//参数可为float /double 分别用int /long 接收

三、字符串类

1.字符串空格分隔

  • String [] Str=in.nextLine().split(" +");//碰到一个或多个空格就分开。

2.字符串替换

  • 字符串去除空格 String.replaceAll(“ ”,””);

3.字符串和字符数组相互转换:

  • 串=String.valueOf(字符数组);
  • 字符数组=串.toCharArray();

4.字符串反转:

5.字符串是否包含某子串

  • s2.contains(s1);
StringBuffer sb=new StringBuffer(s1);
String s2=sb.reverse().toString();

6.正则表达式a{n}

  • s.replace(“a{6}”,""} :表示清除s中连续出现的6个a.

四、集合类

1.集合的遍历

Iterator it = list.iterator();
While(it.hasNext()){
Int a=in.next();
}

2.hashmap排序

2.1根据key排序:

HashMap<Integer,Integer> h=new HashMap<Integer,Integer>();
ArrayList a=new ArrayList(h.keySet());
Collections.sort(a);
再用a充当h的key,遍历得到value。

2.2根据value排序:

public static Map<Integer,Integer>map=new HashMap<Integer,Integer>();
List<Map.Entry<Integer,Integer>>l=new ArrayList<Map.Entry<Integer,Integer>>(map.entrySet());
Collections.sort(l, new Comparator<Map.Entry<Integer,Integer>>(){
@Override
public int compare(Map.Entry<Integer,Integer>o1,Map.Entry<Integer,Integer>o2) {
return (o1.getValue()).compareTo(o2.getValue());//此时为升序,改变o1,o2位置可换位降序
}
});

3. 遍历hashMap

Iterator<Map.Entry<Integer, Integer>> it=hm.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Integer, Integer> t=it.next();
int tempx=t.getKey();
int tempy=t.getValue();
}

4.map无键值对时返回值

  • 当map中无key_value 的映射时,返回Null.

五、其他类

1.计算程序运行时间

long startTime = System.currentTimeMillis(); // 获取开始时间
long endTime = System.currentTimeMillis(); // 获取结束时间
System.out.println("程序总运行时间: " + (endTime - startTime) + “ms”);

2.快速读入输出:

  • 快读
    StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    //读数字
    in.nextToken();
    int n=(int) in.nval;
    //读字符
    in.nextToken();
    int n=(int) in.sval;
  • 快输出:
    PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); // 用于输出的对象
    out.println(n);
    out.printf("%d ",n);//格式化
    out.flush();//不管用上述的哪一种输出,最后记得flush

3.判断数组是否相等:

  • Arrays.equals(a,b);

4.将控制台数据输出到文件

//设置后直接会输入到项目下面的文件下,刷新项目就能看到

  • System.setOut(new PrintStream(“s.txt”));

六、算法

判断素数&计算素数个数
import java.util.Scanner;

public class Prime {
	
	//判断是否为素数
	public static boolean isPrime(int n){
		if(n==1)return false;
		if(n==2||n==3)return true;
		double sqrt=Math.sqrt(n);
		for(int i=2;i<=sqrt;i++){
			if(n%i==0){
				return false;
			}
		}
		return true;
	}
	public static void main(String[] args) {
		Scanner in=new  Scanner(System.in);
		//判断t是否为素数
		int t=in.nextInt();
		System.out.println(isPrime(t));
		
		//计算到n时素数的个数
		long sum=0;
		int n=in.nextInt();
		int suShu[]=new int[n+1];//用0表示素数,1表示非素数
		for(int i=2;i<=n;i++){
			if(suShu[i]==0){
				for(int j=i*2;j<=n;j+=i) suShu[j]=1;
			}
		}
		for(int i=2;i<=n;i++){
			if(suShu[i]==0)sum++;
		}
		System.out.println(sum);
		

	}

}



全排列An&组合Cn
public class 排列组合 {
//全排列An
	public static void A(int a[],int []visited,int n,int temp[]){
		if(n==a.length){
			for(int t:temp)System.out.print(t+" ");
			Asum++;
			System.out.println();
			return;
		}
		for(int i=0;i<a.length;i++){
			if(visited[i]==0){
				temp[n]=a[i];
				visited[i]=1;
				A(a,visited,n+1,temp);
				visited[i]=0;
			}
		}
	}
	//组合Cn
	public static void C(int a[],int start,int k,int temp[]){
		if(k==temp.length){
			Csum++;
			for(int t:temp)System.out.print(t+" ");
			System.out.println();
			return;
		}
		for(int i=start;i<a.length;i++){
			temp[k]=a[i];
			C(a,i+1,k+1,temp);
		}
	}
	public static int Csum;//存放Cn序列总数
	public static int Asum;//存放An序列总数
	public static void main(String[] args) {
		int a[]={5,1,7,8,6,2};
		//全排列An
		int temp[]=new int[a.length];
		int visited[]=new int[a.length];
		A(a,visited,0,temp);//a 表示原始数组;visited 为访问数组,0表示未访问,1表示已经访问;0表示从第一个位置开始填数;temp用于存放每次的排序结果
		System.out.println("共:"+Asum);
		//组合Cn
		int k=4;//从数组中选三个
		int temp2[]=new int[k];
		C(a,0,0,temp2);//a 表示原始数组;第一个0表示指向start的位置,为选择填数的起始位置;第二个0表示从第一个位置开始填数;temp用于存放每次的排序结果
		System.out.println("共:"+Csum);
	}
}
堆排序
public class HeapSort {
	//heapify函数
	public static void heapify(int []tree,int n,int i){
		if(i==n){//到最后节点跳出
			return;
		}
		int c1=2*i+1;
		int c2=2*i+2;
		int maxIndex=i;
		if(c1<n&&tree[c1]>tree[maxIndex]){//获得最小节点位置
			maxIndex=c1;
		}
		if(c2<n&&tree[c2]>tree[maxIndex]){//获得最小节点位置
			maxIndex=c2;
		}
		if(maxIndex!=i){
			int temp=tree[maxIndex];tree[maxIndex]=tree[i];tree[i]=temp;
			heapify(tree,n,maxIndex);//再将交换节点位置处的元素进行heapify操作
		}
	}
	//创建堆
	public static void build_heap(int []tree){
		int last_node=tree.length-1;
		int last_parent=(last_node-1)/2;//从最后一个父节点开始,向前依次做heapify操作
		for(int i=last_parent;i>=0;i--){
			heapify(tree,tree.length,i);
		}
	}
	//堆排序
	public static void heap_sort(int[]tree){
		build_heap(tree);//先建堆
		for(int i=tree.length-1;i>=0;i--){//i从最后一个元素开始,依次向前(i--),分别与首节点交换位置,交换位置后立刻对首节点进行n-i的heapify操作,这样能保证每次交换的首元素都是最大的
			int temp=tree[i];
			tree[i]=tree[0];
			tree[0]=temp;
			heapify(tree,i,0);
		}
	}
	public static void main(String[] args) {
		//测试
		int []a={2,5,3,1,11,5,5,595,9,5,4,4,8,4,54,1,1,12,1,10,4};
		heap_sort(a);
		for(int t:a)System.out.println(t);
	}
}


bfs
static void BFS(ArrayList<Integer> []al,int s){
		//初始化队列,加入起始元素s,并设置其已经被访问,且父节点置为-1(结束标志)
		LinkedList<Integer> l=new LinkedList<Integer>();
		l.add(s);
		visited[s]=1;
		parent[s]=-1;
		//进入循环体
		while(l.size()>0){
			//出队
			int vertex=l.pollFirst();//根节点
			//遍历其叶子节点
			for(int i=0;i<al[vertex].size();i++){
				int node=al[vertex].get(i);
				if(visited[node]==0){//若未被访问,则加入队列,并设置其已经被访问,且父节点置为当前出队元素
					l.add(node);
					parent[node]=vertex;
					visited[node]=1;
				}
			}
		}
	}
dijkstra
static void DijkStra(ArrayList<Vertex> []al,int s){
		//初始节点入队
		Map<Integer,Integer>map=new HashMap<Integer,Integer>();
		map.put(0, s);
		//设置初始节点的相关属性
		distance[s]=0;
		parent[s]=-1;
		while(map.size()>0){
			//将队列排序
			List<Map.Entry<Integer,Integer>>l=new ArrayList<Map.Entry<Integer,Integer>>(map.entrySet());
			Collections.sort(l, new Comparator<Map.Entry<Integer,Integer>>(){
				@Override
				public int compare(Map.Entry<Integer,Integer>o1,Map.Entry<Integer,Integer>o2) {
					return (o1.getValue()).compareTo(o2.getValue());
				}
			});
			//将队列中最小距离的根节点取出,并设置已访问。
			int vertex=l.get(0).getKey();
			map.remove(l.get(0).getKey());
			for(int i=0;i<al[vertex].size();i++){
				//获得叶子节点的id 和 距离
				int node=al[vertex].get(i).id;
				int distance2=al[vertex].get(i).value;
				//判断当前距离是否最小(或者说是比上次的小),然后更新
				int distance12=distance[vertex]+distance2;
				if(distance12<distance[node]){
					map.put(node,distance12);
					parent[node]=vertex;
					distance[node]=distance12;
				}
			}	
		}
	}
KMP
public class KMP {
	//pattern 原字符串,prefix 每个字符对应重复的字符个数,n字符串长度
	public static void prefix_table(char []pattern,int[]prefix,int n){
		prefix[0]=0;
		for(int i=1;i<n;i++){
			int j=i;	//j:比较位置
			while(j>0){//若与前一个字符的prefix对应位置的字符j不相等,则再
				//与j前一个字符的prefix对应的值的字符对比
				j=prefix[j-1];
				if(pattern[i]==pattern[j]){
					prefix[i]=j+1;//最后如果 一个相等的都没找到,结果就为默认值0.
					break;
				}
			}
		}
		int m=prefix.length;
		for(int j=m-1;j>0;j--){
			prefix[j]=prefix[j-1];
		}
		prefix[0]=-1;
	}
	public static void move_prefix_table(int[]prefix,int n){	
	}
	public static void KMP_search(char[]pattern,char[]text){
		//n ,m分别表示 pattern,text 的字符长度
		int n=pattern.length;
		int m=text.length;
		int prefix[]=new int[n];
		prefix_table(pattern,prefix,n);
		int i=0,j=0;//分别指向pattern 和 text 的首位置
		while(j<m){
			//System.out.println(i+" "+j);
			if(i==n-1&&pattern[i]==text[j]){
				System.out.println("找到位置:"+(j-i));
				i=prefix[i];
			}
			if(pattern[i]==text[j]){
				i++;
				j++;
			}else{
				i=prefix[i];
				if(i==-1){//当第一个元素都不相等的时候,i指向pattern中第一个元素,j指向text中的下一个元素。
					i=0;
					j++;
				}
			}
		}
	}
	public static void main(String[] args) {
		char []pattern="A".toCharArray();
		char[]text="BABC".toCharArray();
		KMP_search(pattern,text);
	}
}
01背包
public static void bag(){
		for(int i=1;i<=m;i++){
			for(int j=1;j<=N;j++){
				if(w[i]>j){
					f[i][j]=f[i-1][j];
				}else{
					int xuan=f[i-1][j-w[i]]+v[i]*w[i];
					int buxuan=f[i-1][j];
					f[i][j]=Math.max(xuan, buxuan);
				}
			}
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值