zoukankan      html  css  js  c++  java
  • 算法学习篇(未完)

    声明:所有题目都是自己曾经做过,也只作了部分测试,一定存在错漏之处,如能帮忙指出,感激不尽。其他题目等整理之后再更新

    1.求一个数字的二进制表示有多少个1

    public class CountOfOne {
    	public static void main(String[] args) {
    		//求一个数字的二进制表示有多少个1
    		int number=-1;
    		print(number);
    		System.out.println(NumberOf1(number));
    	}
    	public static int NumberOf1(int n){
    		int count=0;
    		while(n!=0){
    			count++;
    			n=(n-1)&n;
    			print(n);
    		}
    		return count;
    	}
    	public static void print(int n){
    		String binary=Integer.toBinaryString(n);
    		int count=32-binary.length();
    		for(int i=0;i<count;i++){
    			System.out.print("0");
    		}
    		System.out.println(binary+" "+n);
    	}
    }
    

    2.最短路径

    题目路径:http://acm.hdu.edu.cn/vcontest/vtl/problem/showproblem/vtlid/4642/problemid/1011

    public class Shortest {
    //http://acm.hdu.edu.cn/vcontest/vtl/problem/showproblem/vtlid/4642/problemid/1011
    	private int[][] table=new int[10][10];
    	private boolean[][] map=new boolean[10][10];
    	private void initTable(){
    		int i=5;
    		int j=4;
    		int number=2;
    		table[i][j]=1;
    		int a=1,b=2;
    		while(number<73){
    			for(int d=0;d<a;d++){
    				table[i][++j]=number++;
    			}
    			for(int d=0;d<a;d++){
    				table[--i][j]=number++;
    			}
    			a+=2;
    			for(int d=0;d<b;d++){
    				table[i][--j]=number++;
    			}
    			for(int d=0;d<b;d++){
    				table[++i][j]=number++;
    			}
    			b+=2;		
    		}
    		for(int d=0;d<a;d++){
    			table[i][++j]=number++;
    		}
    		for(int d=0;d<a;d++){
    			table[--i][j]=number++;
    		}
    		for(int d=0;d<b-1;d++){
    			table[i][--j]=number++;
    		}
    	}
    	private void initMap(){
    		map[0][3]=true;
    		map[1][4]=map[1][6]=true;
    		map[2][1]=map[2][7]=map[2][9]=true;
    		map[3][0]=map[3][2]=map[3][6]=true;
    		map[4][3]=map[4][5]=map[4][7]=true;
    		map[5][2]=map[5][5]=map[5][6]=map[5][8]=true;
    		map[6][1]=map[6][3]=true;
    		map[7][0]=map[7][4]=true;
    		map[8][1]=map[8][5]=map[8][9]=true;
    		map[9][0]=map[9][6]=true;
    	}
    	private int aim;
    	public Shortest(int a,int b){
    		initTable();
    		initMap();
    		aim=b;
    		for(int i=0;i<10;i++)
    			
    			for(int j=0;j<10;j++){
    				if(table[i][j]==a){
    					process(i,j,0);
    					break;
    				}
    			}
    		if(bestPath==1000000){
    			System.out.println("impossible");
    		}else{
    			System.out.println(bestPath);
    		}
    	}
    	//表示很远
    	private int bestPath=1000000;
    	
    	private void process(int i,int j,int path){
    		if(table[i][j]==aim){
    			if(path<bestPath){
    				bestPath=path;
    			}
    		}
    		map[i][j]=true;
    		//没有数据 有数据的为true,
    		if(i-1>=0&&!map[i-1][j]){
    			//向上	
    			process(i-1,j,path+1);
    		}
    		if(i+1<=9&&!map[i+1][j]){
    			//向下
    			process(i+1,j,path+1);
    		}
    		if(j-1>=0&&!map[i][j-1]){
    			//向左
    			process(i,j-1,path+1);
    		}
    		if(j+1<=9&&!map[i][j+1]){
    			//向右
    			process(i,j+1,path+1);
    		}
    		map[i][j]=false;
    	}
    	public static void main(String[] args) {
    		int start=9;
    		int end=32;
    		new Shortest(start,end);
    	}
    	
    }


    3.青蛙跳跃

    游戏地址:http://www.macroblue.net/bbs/ShowPost.asp?ThreadID=5932

    六个位置从左到右依次编号为:1,2,3,4,5,6

    import java.util.ArrayList;
    import java.util.List;
    
    public class FrogJump {
    	private int[] pos=new int[]{1,1,1,0,2,2,2};
    	private int count=0;
    	private List<String> content=new ArrayList<String>();
    	public void jump(){
    		
    		if(isComplete()){
    			
    			for(String str:content){
    				System.out.println(str);
    			}
    			System.out.println("总共移动的次数为:"+count+"次");
    			System.out.println("=======================");
    		}
    		for(int i=0;i<7;i++){
    			int type=canJump(i);
    			if(type!=-1){
    				content.add(print(i,type));
    				swap(type,i);
    				count++;
    				jump();
    				swap(type,i);
    				count--;
    				content.remove(count);
    			}
    		}
    
    	}
    	private String print(int start,int end){
    		//int type=pos[start];
    		return (start+1)+"位置的青蛙跳到空地"+(end+1);
    	}
    	private boolean isComplete(){
    		boolean result=true;
    		for(int i=0;i<3;i++){
    			if(pos[i]!=2)return false;
    		}
    		for(int i=4;i<7;i++){
    			if(pos[i]!=1)return false;
    		}
    		return result;
    
    	}
    	private void swap(int i,int j){
    		int temp=pos[i];
    		pos[i]=pos[j];
    		pos[j]=temp;
    	}
    	
    	private int canJump(int index){
    		if(pos[index]==0)return -1;
    		//左边的青蛙
    		if(pos[index]==1){
    			if(index==6)return -1;
    			if(pos[index+1]==0){
    				return index+1;
    			}else if((index<=4&&pos[index+2]==0)){
    				return index+2;
    			}
    		}else{//右边的青蛙
    			if(index==0)return -1;
    			if(pos[index-1]==0){
    				return index-1;
    			}else if((index>=2&&pos[index-2]==0)){
    				return index-2;
    			}	
    		}
    		return -1;
    	}
    	public static void main(String[] args) {
    		new FrogJump().jump();
    	}
    	
    }

    输出:

    3位置的青蛙跳到空地4
    5位置的青蛙跳到空地3
    6位置的青蛙跳到空地5
    4位置的青蛙跳到空地6
    2位置的青蛙跳到空地4
    1位置的青蛙跳到空地2
    3位置的青蛙跳到空地1
    5位置的青蛙跳到空地3
    7位置的青蛙跳到空地5
    6位置的青蛙跳到空地7
    4位置的青蛙跳到空地6
    2位置的青蛙跳到空地4
    3位置的青蛙跳到空地2
    5位置的青蛙跳到空地3
    4位置的青蛙跳到空地5
    总共移动的次数为:15次
    =======================
    5位置的青蛙跳到空地4
    3位置的青蛙跳到空地5
    2位置的青蛙跳到空地3
    4位置的青蛙跳到空地2
    6位置的青蛙跳到空地4
    7位置的青蛙跳到空地6
    5位置的青蛙跳到空地7
    3位置的青蛙跳到空地5
    1位置的青蛙跳到空地3
    2位置的青蛙跳到空地1
    4位置的青蛙跳到空地2
    6位置的青蛙跳到空地4
    5位置的青蛙跳到空地6
    3位置的青蛙跳到空地5
    4位置的青蛙跳到空地3
    总共移动的次数为:15次
    =======================
    


    4.将小写的数字转换成中文大写数字,如:456789  对应中文大写的:肆拾伍万陆仟柒佰捌拾玖元整

    public class MoneyReverse {
    	public static void main(String[] args) {
    		
    		String str=new MoneyReverse().process("456789");
    		System.out.println(str);
    	}
    	private char[] map=new char[]{'壹','貳','弎','肆','伍','陆','柒','捌','玖'};
    	private String[] typeMap=new String[]{"","拾","佰","仟","万","亿"}; 
    	private String [] lastMap=new String[]{"元整","万","亿","万亿"};
    	public String process(String str){
    		//去掉前面的零
    		str=str.replaceFirst("^0*", "");
    		int i=str.length();
    		int count=i%4==0?i/4:i/4+1;
    		String[] part=new String[count];
    		int t=0;
    		for(;t<count-1;t++){
    			part[t]=str.substring(i-4*(t+1),i-4*t);
    		}
    		part[count-1]=str.substring(0,i-4*t);	
    		t=count-1;
    		StringBuilder builder=new StringBuilder();
    		for(;t>=0;t--){
    			builder.append(processPart(part[t], t));
    		}
    		return builder.toString();
    	}
    	private String processPart(String number,int type){
    		int count=number.length();
    		String result="";
    		for(int i=count-1;i>=0;i--){
    			char c=number.charAt(i);
    			if((i!=count-1&&c=='0'&&number.charAt(i+1)!='0')||(i==0&&c=='0')){
    				result="零"+result;
    			}
    			else if(c!='0'){
    				result=map[c-49]+typeMap[count-1-i]+result;
    			}
    		}		
    		return result+lastMap[type];
    	}
    	
    }


    5.将1~9九个数字,组合成三个三位数A,B,C使其满足:B/A=2 C/A=3 有多少种这种组合?

    public class NumberMerger {
    	//false表示还没有使用
    	private boolean[] map=new boolean[9];
    	
    	public void process(){
    	
    		int firstNumber=0;
    		//第一个数
    		for(int i=1;i<=3;i++){
    			//已用
    			map[i-1]=true;
    			firstNumber+=i*100;
    			//第二个数
    			for(int j=1;j<=9;j++){
    				if(!map[j-1]){
    					map[j-1]=true;
    					firstNumber+=j*10;
    					for(int k=1;k<=9;k++){
    						if(!map[k-1]){
    							map[k-1]=true;
    							firstNumber+=k;
    							validate(firstNumber);
    							firstNumber-=k;
    							map[k-1]=false;
    						}
    					}
    					firstNumber-=j*10;
    					
    					map[j-1]=false;
    				}
    			}
    			firstNumber-=i*100;
    			map[i-1]=false;
    		}
    		
    	}
    	public void validate(int number){
    
    		int secondNumber=number*2;
    		int thridNumber=number*3;
    		if(secondNumber>=1000||thridNumber>=1000)return;
    		String text=""+secondNumber+thridNumber;
    		if(text.contains("0"))return;
    		int m=100;
    		String mapProcess="";
    		for(int i=0;i<3;i++){
    			//已经使用过
    			if(map[secondNumber/m-1]||map[thridNumber/m-1]){
    				if(!"".equals(mapProcess)){
    					for(int t=0;t<mapProcess.length();t++){
    						map[mapProcess.charAt(t)-49]=false;
    					}
    				}
    				return;
    			}else{
    				map[secondNumber/m-1]=true;
    				map[thridNumber/m-1]=true;
    				mapProcess=mapProcess+(secondNumber/m);
    				mapProcess=mapProcess+(thridNumber/m);
    				secondNumber=secondNumber%m;
    				thridNumber=thridNumber%m;
    				m/=10;
    			}
    		}
    		for(int t=0;t<mapProcess.length();t++){
    			map[mapProcess.charAt(t)-49]=false;
    		}
    		System.out.println(number+","+2*number+","+3*number);
    	}
    	
    	
    	public static void main(String[] args) {
    		new NumberMerger().process();
    	}
    }


    6.求一个数字序列中最长连续递增子序列有多少个?

    如这样一组序列:17 2 5 77 99 93 11 97 65 35 

    其最长连续递增子序列是从第二个数字2到数字99,一共4个。

    import java.util.Random;
    public class SlopeUp {
    	public static void main(String[] args) {
    		int count=10;
    		int[] nums=new int[count];
    		Random random=new Random();
    		for(int i=0;i<count;i++){
    			nums[i]=random.nextInt(100);
    			System.out.print(nums[i]+" ");
    		}
    		System.out.println();
    		new SlopeUp().process(nums);
    	}
    	
    	private int[] a; //a[i]表示从开始到i最长连续递增子序列个数,最后的结果为:a[a.length-1]
    	private int[] b; //b[i]表示到当前i位置有多少个连续递增个数,如-1,2,4,0,3 则b[2]=3;b[4]=2
    	public void process(int[] nums){
    		a=new int[nums.length];
    		b=new int[nums.length];	
    		for(int i=1;i<nums.length;i++){
    			
    			if(nums[i]>nums[i-1]){
    				b[i]=b[i-1]+1;
    				if(b[i]+1>a[i-1]){
    					System.out.println("The End Number Is:"+nums[i]);
    					a[i]=b[i]+1;
    				}else{
    					a[i]=a[i-1];
    				}
    			}else{
    				a[i]=a[i-1];
    			}
    		}
    		System.out.println(a[a.length-1]);
    	}
    	
    }

    7.假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字母数相对少一些。从算法是讲,什么方法能最快的查出所有小字符串里的字母在大字符串里都有?
    比如,如果是下面两个字符串:
    String 1: ABCDEFGHLMNOPQRS
    String 2: DCGSRQPOM
    答案是true,所有在string2里的字母string1也都有。 

    解法1:

    public class StringProcess01 {
    	public static void main(String[] args) {
    		String s1="ABCDEFGHLMNOPQRS";
    		String s2="DCGSRQPOM";
    		new StringProcess01().process(s1,s2);
    	}
    	
    	public void process(String lengthStr,String ShortStr){
    		boolean hash[]=new boolean[26];
    		char[] scs=ShortStr.toCharArray();
    		int count=0;//短字符串中不同字符的个数
    		for(int i=0;i<scs.length;i++){
    			int index=scs[i]-'A';
    			if(!hash[index]){//为了保障count的准确
    				hash[index]=true;
    				count++;
    			}
    			
    		}
    		char[] lcs=lengthStr.toCharArray();
    		for(int i=0;i<lcs.length;i++){
    			int index=lcs[i]-'A';
    			if(hash[index]){
    				hash[index]=false;
    				count--;
    				if(count==0)break;
    			}
    		}
    		if(count==0){
    			System.out.println("True");
    		}else{
    			System.out.println("False");
    		}
    	}
    }


    解法2

    import java.math.BigInteger;
    /*
    假设我们有一个一定个数的字母组成字串,我给每个字母分配一个素数,
    从2开始,往后类推。这样A将会是2,B将会是3,C将会是5,等等。
    现在我遍历第一个字串,把每个字母代表的素数相乘。你最终会得到一个很大的整数,
    对吧?然后——轮询第二个字符串,用每个字母除它。
    如果除的结果有余数,这说明有不匹配的字母。
    如果整个过程中没有余数,你应该知道它是第一个字串恰好的子集了。
    */
    public class StringProcess01_02 {
    	public static void main(String[] args) {
    		String str1="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    		String str2="SDFF";
    		new StringProcess01_02().process(str1, str2);
    	}
    	
    	public void process(String lengthStr,String shortStr){
    		int[] primeNumber=new int[]{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,61, 67, 71, 73, 79, 83, 89, 97, 101};
    		BigInteger mulValuse=BigInteger.valueOf(1);
    		char[] lca=lengthStr.toCharArray();
    		for(int i=0;i<lca.length;i++){
    			int index=lca[i]-'A';
    			//表示之前没有出现过该字符,可以防止相同的素数一直相乘
    			String re=mulValuse.remainder(BigInteger.valueOf(primeNumber[index])).toString();
    			if(!"0".equals(re)){
    				mulValuse=mulValuse.multiply(BigInteger.valueOf(primeNumber[index]));
    				//System.out.println(mulValuse.toString());
    			}
    			
    		}
    		
    		char[] sca=shortStr.toCharArray();
    		boolean temp=true;
    		for(int i=0;i<sca.length;i++){
    			int index=sca[i]-'A';
    			String re=mulValuse.remainder(BigInteger.valueOf(primeNumber[index])).toString();
    			if(!"0".equals(re)){
    				//只要第一个出现的不合法的字符则马上结束
    				//当数据多时,效率将会非常显著的提高
    				temp=false;
    				break;
    			}
    		}
    		if(temp){
    			System.out.println("True");
    		}else{
    			System.out.println("False");
    		}
    	}
    }


    8.三色旗算法(注意看清题意,否则可能不能理解代码)

    题意可以查看:http://hi.baidu.com/de1zhanjie/item/bdac2bbab11d12afeaba9355

    //关键:两头向中间找,找过的可以进行交换,还没有找过的不能处理
    public class ThreeColorFlag02 {
    	private int blue; //blue指针左边的值一定为蓝色
    	private int white; //white一直向右移动,但为白色,则直接移动,当为红色,和红色指针交换,当为蓝色指针,和蓝色指针交换
    	private int red; //red指针右边的值一定为红色
    	private char[] source;
    	public ThreeColorFlag02(char[] s){
    		this.source=s;
    		blue=0; 
    		white=0;
    		red=source.length-1;
    		process();
    	}
    	public void process(){
    		//blue指针指向的为:非蓝色旗
    		while(source[blue]=='蓝'){
    			blue++;
    			white++;
    		}
    		//red指针指向的为:非红色旗
    		while(source[red]=='红'){
    			red--;
    		}
    		//当白色指针超过红色指针,则表示结束
    		while(white<=red){
    			if(source[white]=='红'){
    				swap(white,red);
    				//必须减1,否则刚刚交换完,该位置必定为红
    				red--;
    				while(source[red]=='红'){
    					red--;
    				}
    			}
    			//如果刚刚和red交换过,则可能为蓝色,或者白色
    			//否则,为白色
    			while(source[white]=='白'){
    				white++;
    			}
    			//此时white可能指向蓝色或者红色
    			if(source[white]=='蓝'){
    				swap(white,blue);//蓝色指针为遍历过的指针,所以可以交换
    				white++;
    				blue++;
    			}
    		}
    	}
    	private void swap(int i,int j){
    		char temp=source[i];
    		source[i]=source[j];
    		source[j]=temp;
    	}
    	public static void main(String[] args) {
    		char[] source=new char[]{'红','白','蓝','白','白','蓝','红','蓝','白','红'};
    		new ThreeColorFlag02(source);
    		System.out.println(Arrays.toString(source));
    	}
    }


    9.桶排序(看代码前要先理解桶排序的原理)

    public class BucketSort {
    	/**
    	 * 
    	 * @param data 要进行排序的数据
    	 * @param min 数据中最小的数据
    	 * @param max 数据中最大的数据
    	 */
    	public void bucketSort(int[] data,int min,int max){
    		int arrayLength=data.length;
    		//临时数组,data数组的拷贝
    		int[] tmp=new int[arrayLength];
    		System.arraycopy(data, 0, tmp, 0, arrayLength);
    		//桶数组
    		int[] buckets=new int[max-min];
    		for(int i=0;i<arrayLength;i++){
    			//记录每个数出现的次数
    			buckets[data[i]-min]++;
    		}
    		//对桶进行处理
    		for(int i=1;i<max-min;i++){
    			buckets[i]=buckets[i]+buckets[i-1];
    		}
    		//根据桶的信息来确定数据的位置
    		//tmp.Data和该值对应的具体位置的映射关系为:
    		//tmp.Data-映射->buckets.Index-得到->buckets.Data
    		//buckets.Data-映射->data.Index-确定->data.Data
    		//为了保证算法的稳定性,从最大索引开始
    		for(int i=arrayLength-1;i>=0;i--){
    			data[--buckets[tmp[i]-min]]=tmp[i];
    		}
    	}
    	public static void main(String[] args) {
    		int[] data=new int[]{9,5,-1,8,5,7,3,-3,1,3};
    		//因为在bucketSort方法中算桶个数是max-min,所以这里的max应该要比实际的大1
    		new BucketSort().bucketSort(data, -3, 10);
    		for(int num:data){
    			System.out.print(num+" ");
    		}
    	}
    }


    10.建立最大堆

    public class MaxHeap {
    	public static void main(String[] args) {
    		int[] source=new int[]{3,24,-1,10,5};
    		new MaxHeap().createHeap(source);
    		System.out.println(Arrays.toString(source));
    	}
    	private int[] source;
    	private int length;
    	public void createHeap(int[] s){
    		this.source=s;
    		length=this.source.length-1;
    		for(int i=length/2;i>=0;i--){
    			process(i);
    		}
    	}
    	private void process(int index){
    		int left=getLeftIndex(index);
    		int right=getRightIndex(index);
    		int maxIndex=index;
    		//右子树为有效子树
    		if(right<=length&&source[index]<source[right]){
    				maxIndex=right;
    		}
    		if(left<=length&&source[maxIndex]<source[left]){
    				maxIndex=left;
    		}
    		//最大值不是本身
    		if(maxIndex!=index){
    			swap(maxIndex,index);
    			//这一步很重要,要递归处理交换后的新节点,保证所有的结点都符合最大堆的特点
    			process(maxIndex);
    		}
    	}
    	//交换
    	private void swap(int i,int j){
    		int temp=source[i];
    		source[i]=source[j];
    		source[j]=temp;
    	}
    	private int getLeftIndex(int index){
    		//下标从0开始
    		return 2*index+1;
    	}
    	private int getRightIndex(int index){
    		return 2*index+2;
    	}
    	
    }


    11.打印中文字符序列的每个字符的拼音的第一个字母:如输入:"直来直往",则输出:“ZLZW”

    import java.io.UnsupportedEncodingException;
    public class js_02 {
    	public static void main(String[] args) {
    		new js_02().new answer("我深爱我的家人");
    	}	
    	private class answer{
    		private int[][] res=new int[23][2];
    		private String[] word={"啊","芭","擦","搭","蛾","发","噶","哈","击","喀","垃","妈","拿","哦","啪","期","然","撒","塌","挖","昔","压","匝"};
    		private char[] cs={'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','W','X','Y'};
    		public answer(String str){
    			iniRes();
    			process(str);
    		}
    		private void iniRes(){
    			for(int i=0;i<word.length;i++){
    				try {
    					byte[] bs=word[i].getBytes("GB2312");
    					res[i][0]=bs[0]&0xff;
    					res[i][1]=bs[1]&0xff;
    				} catch (UnsupportedEncodingException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    			for(int i=0;i<res.length;i++){
    				
    				for(int j=0;j<2;j++){
    					System.out.print(res[i][j]+",");
    				}
    				System.out.println();
    			}		
    			
    		}
    		public void process(String str){
    			
    			for(int i=0;i<str.length();i++){
    				String word=str.substring(i, i+1);
    				try {
    					byte[] b=word.getBytes("GB2312");
    					int first=b[0]&0xff;
    					int second=b[1]&0xff;
    					boolean isZ=true;
    					for(int t=0;t<res.length-1;t++){
    						if(first>=res[t][0]&&first<res[t+1][0]){
    							System.out.print(cs[t]);
    							isZ=false;
    							break;	
    						}else if(first>=res[t][0]&&first==res[t+1][0]){//first==res[t][0]&&first==res[t+1][0]
    							if(second<res[t+1][1]){
    								System.out.print(cs[t]);
    								isZ=false;
    								break;	
    							}
    						}
    					}
    					if(isZ){
    						System.out.print('Z');
    					}
    				} catch (UnsupportedEncodingException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    		
    	}
    		
    	
    }
    




  • 相关阅读:
    决战72hours
    学习中的十七条建议
    数学建模终结篇
    数学建模(7)建模开始
    ASP升级程序
    为blog挑选logo
    Mysql源代码分析系列(4): 主要调用流程(续)转载
    AS学习步骤
    什么是敏捷软件测试[转]
    Mysql源代码分析(6): Plugin架构介绍(续)转载
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3146806.html
Copyright © 2011-2022 走看看