算法

5 篇文章 0 订阅

############################################

1.****八皇后问题

package test2;

public class EightQueen {
    private static final boolean AVAILABLE = true;
    private int squares = 8, norm = squares - 1;
    private int positionInRow[] = new int[squares];
    private int p = -1;
    private boolean[] rows = new boolean[squares];
    private boolean[] column = new boolean[squares];
    private boolean[] leftDiagonal = new boolean[2 * squares - 1];
    private boolean[] rightDiagonal = new boolean[2 * squares - 1];
    private static int howMany = 0;

    public EightQueen() {
        // To complete the initialization work for the
        // column,leftDiagonal,rigthDiagonal.
        for (int i = 0; i < squares; i++) {
            rows[i] = AVAILABLE;
            column[i] = AVAILABLE;
            positionInRow[i] = -1;
        }
        for (int i = 0; i < 2 * squares - 1; i++) {
            leftDiagonal[i] = AVAILABLE;
            rightDiagonal[i] = AVAILABLE;
        }

    }

    public void printResults(int[] columns) {
        int row, col;
        System.out.println("八皇后问题的第 " + howMany + " 种解法");
        System.out.print("八皇后问题的结果为:");
        for (int e : columns) {
            System.out.print(e);
        }
        System.out.println("\n具体的图示如下图所示:");
        for (row = 0; row < squares; row++) {
            for (col = 0; col < squares; col++) {
                if (col == positionInRow[row]) {
                    System.out.print("@");
                } else {
                    System.out.print("*");
                }
            }
            System.out.println();
        }
        System.out.println();
    }

    public void putQueen() {
        int row = 0, col;
        while (true) {
            for (col = p + 1; col < squares; col++) {
                if (rows[row] == AVAILABLE && column[col] == AVAILABLE
                        && leftDiagonal[row + col] == AVAILABLE
                        && rightDiagonal[row - col + norm] == AVAILABLE) {
                    break;
                }
            }
            // 在当前的行里面找到了可以放置皇后的位置
            if (col < squares) {
                rows[row] = !AVAILABLE;
                column[col] = !AVAILABLE;
                leftDiagonal[row + col] = !AVAILABLE;
                rightDiagonal[row - col + norm] = !AVAILABLE;
                positionInRow[row] = col;
                p = col;
            } else// 如果当前行没办反放置皇后了,那么回溯
            {
                if (row > 0)// 到前一行
                {
                    row--;
                    p = positionInRow[row];
                    rows[row] = AVAILABLE;
                    column[p] = AVAILABLE;
                    leftDiagonal[row + p] = AVAILABLE;
                    rightDiagonal[row - p + norm] = AVAILABLE;
                    positionInRow[row] = -1;
                    continue;
                } else {
                    break;
                }
            }
            if (row == squares - 1) {
                howMany += 1;
                printResults(positionInRow);
                p = positionInRow[row];
                rows[row] = AVAILABLE;
                column[p] = AVAILABLE;
                leftDiagonal[row + p] = AVAILABLE;
                rightDiagonal[row - p + norm] = AVAILABLE;
                positionInRow[row] = -1;
                continue;
            } else {
                row++;
                p = -1;
                continue;
            }
        }
    }

    public static void main(String args[]) {
        EightQueen eightQueens = new EightQueen();
        eightQueens.putQueen();
        System.out.println("皇后问题一共有" + howMany + "种解法");
    }

}


############################################

2.************汉诺塔问题

package test2;

public class HanNuoTa {
    public static void main(String args[]){
        HanNuoTa hnt=new HanNuoTa();
        hnt.heneita(20, 'a', 'b', 'c');
    }
    
    /*
     * 假设柱子编号为a,b,c号,盘子数目为n
     * 问题:将n个盘子从a号柱子挪到c号柱子上
     * 解题思路,借助于b号柱子
     */
    public void heneita(int n,char a, char b, char c){
            if(n==1){
                System.out.println("将1号盘子从"+a+"号柱子移动到"+c+"号柱子");
                return;
            }
            heneita(n-1,a,c,b);
            System.out.println("将"+n+"号盘子从"+a+"号柱子移动到"+c+"号柱子");
            heneita(n-1,b,a,c);
    }    
}

#############################################

3.******************杨辉三角问题

4.******************三色旗问题

5.******************费那波切数列

6.******************老鼠走迷宫问题

package test2;


public class MathTest {
    public static void main(String args[]){
        MathTest math=new MathTest();
//        Scanner in=new Scanner(System.in);
//        int i=in.nextInt();
//        System.out.println(math.fnbq(i));
//        System.out.println(math.sumfn(i));
//        System.out.println(math.sumfnbq(i));
        
        /*
         * 杨辉三角第n行
         */
//        int []k;
//        k=math.testArray(i);
//        for(int j=0;j<i;j++)
//            System.out.println(k[j]+" ");
        /*
         * 杨辉三角所有行输出
         */
//        math.print(i);
        
        /*
         * 三色旗
         */
//        int []a=new int[8];
//        System.out.println("红旗输入:0,白旗输入:1,蓝旗输入:2");
//        for(int i=0;i<8;i++)
//            a[i]=in.nextInt();
//        math.Sort(a);
//        for(int i=0;i<8;i++){
//            if(a[i]==0)
//                System.out.print("红旗 ");
//            else if(a[i]==1)
//                System.out.print("白旗 ");
//            else
//                System.out.print("蓝旗 ");
//        }
//        
//        int[][] maze = {{1, 0,0, 0, 1, 1, 0},    
//                {1, 1, 1, 0, 0, 0, 1},    
//                {1, 0, 1, 1, 1, 0, 1},    
//                {1, 0, 0, 1, 0, 1, 0},    
//                {1, 1, 0, 1, 1, 1, 1},    
//                {1, 0, 0, 0, 1, 0, 0},    
//               { 1, 1, 1, 1, 1, 1, 1}};   
//        math.lookPath(maze,maze.length-1,maze[0].length-1);
        
        //math.start();
//        math.intailize(8);                                   /???????????待解决
//        math.eightQueen();
        
        int []k=MathTest.calculateK("abcdfaghbksabcjkl");
        for(int i=0;i<k.length;i++)
            System.out.println(k[i]);
    }
    
    /*
     * 1.求费那波切数列第n项
     */
    public int fnbq(int n){
        if(n==1||n==2)
            return 1;
        else{
            return fnbq(n-1)+fnbq(n-2);
        }
    }
    
    /*
     * 2.求前n项和
     *
     */
    public int sumfn(int i){
        int sum=0;
        for(int j=1;j<=i;j++){
            int k=fnbq(j);
            sum=sum+k;
        }
            
        return sum;
    }
    
    /*
     * 3.前n项和优化
     * s(n)=s(n-1)+f(n)
     */
    public int sumfnbq(int i){
        if(i==1)
            return 1;
        else{
            return sumfnbq(i-1)+fnbq(i);
        }        
    }
    
    
    /*
     * 输出杨辉三角
     */
    public void print(int n){            //n表示一共有n行                         
        for(int j=1;j<=n;j++){          //j表示第几行
        int []z=testArray(j);    
        for(int i=1;i<=n-j;i++)
            System.out.print(" ");
        System.out.print(1);
        int u,k;
        for(u=n-j+2,k=1;u<=n+j-2&&k<z.length-1;){
            System.out.print(" ");
            u++;            
            if(u<=n+j-2){
//                System.out.println(b[k]+b[k++]);
                System.out.print(z[k]);
                u++;
                k++;
            }
        }
        System.out.print(" ");
        if(u<=n+j-2)
        System.out.print(1);
        System.out.println();
        }
    }
    
    //杨辉三角第n行数据
    public int[] testArray(int n){
        int []a=new int [n];
        if(n==1){
            a[0]=1;
            return a;
        }
        else{
            int b[]=testArray(n-1);    //要返回的数组,即记录第n行的数
            a[0]=1;
            a[a.length-1]=1;
            for(int i=1;i<n-1;i++){
                a[i]=b[i-1]+b[i];
            }
            return a;
        }
    }
    
    /*
     * 三色旗问题
     * 0--红旗   1--白旗   2--蓝旗
     */
    public void Sort(int []a){
        int i=0;
        int j=a.length-1;
        int ftmp=-1;
        int ltmp=-1;
        while(i<=j){
            if(a[i]==0){        
                if(iswhite(ftmp))    //是红旗并且前面未出现白旗
                    i++;
                else{                //出现红旗,且前面过出现白旗,将红旗与第一个白旗交换
                    a[i]=1;
                    a[ftmp]=0;       
                    i++;
                    ftmp++;
                }
            }
            else if(a[i]==1){      //白色继续往下走
                if(iswhite(ftmp)){   //未出现白旗,要记下第一次出现的位置
                    ftmp=i;
                    i++;
                }
                else{
                    i++;
                }
            }
            else{                   //出现蓝旗
                if(iswhite(ltmp)){
                    int tmp=a[j];
                    a[j]=2;
                    a[i]=tmp;
                    j--;
                }
            }
        }
    }
    
    //判断是否是首次出现白旗,或者是否出现过白旗
    public boolean iswhite(int i){
        if(i==-1)                //未出现过
            return true;
        else{
            return false;
        }
    }
    
    
    /*
     * 老鼠走迷宫
     */
    public boolean lookPath(int [][]a,int i,int j){
//            if(a[i-1][j]==1&&i>0)
//            lookPath(a,i-1,j);
//            if(a[i][j-1]==1&&j>0)
//            lookPath(a,i,j-1);
            if(i==0&&j==0)
                return true;
            if(i<0)
                return false;
            if(j<0)
                return false;
            if(a[i][j]==1&&(lookPath(a,i-1,j)||lookPath(a,i,j-1))){
                System.out.print("("+i+","+j+")-->");
                return true;
            }
            return false;
    }
    
    
    /*
     * 八皇后问题求解
     *
     */
    private final int flag=1;         //是否被占领
    private final int outflag=0;        
    private int size;
    private int[]location;                    //第几行的皇后占据第几列
    private int[]occupiedcol;                   //占领了第几列
    private int[]occupiedff;                  //占领了那个正对角线
    private int[]occupieddd;                  //占领了那个反斜对角线
    private static int count=0;
    public void intailize(int size){
          this.size=size;
          this.location=new int[size];
          this.occupiedcol=new int[size];
          this.occupiedff=new int[2*size];
          this.occupieddd=new int[2*size];
    }
    public void printLocation(){
        System.out.println("以下是皇后在棋盘上的第"+count+"中摆放位置");
        for(int i=0;i<size;i++)
            System.out.println("行:"+i+"列:"+location[i]);
    }

    public boolean isOccupied(int i,int j){   //判断第(i,j)位置是否被占领
        return occupiedcol[j]==1||occupiedff[i+j]==1||occupieddd[i-j+size-1]==1;
    }
    
    public void setOccuption(int i,int j,int flag){  //宣布占领或者取消占领位置
        occupiedcol[j]=flag;
        occupiedff[i+j]=flag;
        occupieddd[i-j+size-1]=flag;
    }
    
    
    
    /*
     * 递归实现八皇后问题
     */
    /*
    public void place(int i){       //从第i行开始摆放皇后
        for(int j=0;j<size;j++){      //在第i行尝试把皇后放到每一列上
            if(!isOccupied(i,j)){     //判断该位置是否被占领
                location[i]=j;        //才第i行将皇后放到第j列
                setOccuption(i,j,flag);
                if(i<size-1){
                    place(i+1);
                }
                else{
                    count++;
                    printLocation();
                }
                setOccuption(i,j,outflag);     //回溯,撤销占领
            }
        }
    }
    
    public void start(){
        intailize(8);
        place(0);
    }
    */
    
    /*
     * 非递归实现八皇后问题
     * 循环是实现
     */
    public void eightQueen(){   //i表示从第几行开始摆放
            int i;
        for(i=0;i<size;i++){
            for(int j=0;j<size;j++){
                if(!isOccupied(i,j)){
                    location[i]=j;
                    setOccuption(i,j,flag);
                    if(i==size-1){
                        count++;
                        printLocation();
                        setOccuption(i,j,outflag);  //摆放成功,进行上溯
                        continue;
                    }
                    else{
                        break;
                    }
                }
                else if(j==size-1&&i!=0){      //第i行无法摆放皇后的位置 ,进行上溯
                    i--;
                    setOccuption(i,location[i],outflag);
                    j=location[i];
                }
            }
        }
    }
    
    
     /*
     * 计算K值
     */  
    private static int[] calculateK(String mode) {  
        //为了和算法保持一致,使index从1开始,增加一前缀  
        String newMode = "x" + mode;  
        int[] K = new int[newMode.length()];  
        int i = 1;  
        K[1] = 0;  
        int j = 0;  
          
        while(i < mode.length()) {  
            if (j == 0 || newMode.charAt(i) == newMode.charAt(j)){  
                i++;  
                j++;  
                K[i] = j;  
            } else {  
                j = K[j];  
            }  
        }  
          
        return K;  
    }  
    
    
}


###########################################################

7.**************************各种排序问题

package test2;
import java.util.Scanner;

/*
 * 测试list中可不可以放不同的对象,或者基本数据类型和对象可不可以一起存放
 */
public class Test{
    
    public static void main(String args[]){
        Test test=new Test();
        int []a=new int[8];
        Scanner sc=new Scanner(System.in);
        for(int i=0;i<a.length;i++)
            a[i]=sc.nextInt();
//            test.sort(a,0,a.length-1);
//            test.quickSort(a);
//            test.xierSort(a, 3);
//            test.pop(a);
//            test.massSort(a);
            test.uninSort(a, 0,a.length-1);
        for(int i=0;i<a.length;i++)
            System.out.println(a[i]);
    }
    
    
    /**
     * 快速排序
     * @param list
     * @param low
     * @param high
     */
    public void sort(int [] list,int low ,int high){               //递归快速排序
        if (low>high)
            return;
        else{
            int i=getMiddle(list,low,high);
            sort(list,low,i-1);
            sort(list,i+1,high);
        }        
    }
    
    public int getMiddle(int [] list, int low, int high) {          //一次快速排序
        int tmp = list[low];    //数组的第一个作为中轴  
        while (low < high) {  
            while (low < high && list[high] > tmp) {  
                high--;  
            }  
            list[low] = list[high];   //比中轴小的记录移到低端  
            while (low < high && list[low] < tmp) {  
                low++;  
            }  
            list[high] = list[low];   //比中轴大的记录移到高端  
        }  
        list[low] = tmp;              //中轴记录到尾  
        return low;                   //返回中轴的位置  
    }  
    
    
    /**
     * 直接插入排序
     *
     */
    public void quickSort(int [] a){
        for(int j=1;j<a.length;j++)
        for(int i=j;i>0;i--){                    //将a[i]插入前i-1个有序区中
            if(a[i-1]<a[i])
                break;
            else{
                int tmp=a[i];
                a[i]=a[i-1];
                a[i-1]=tmp;
            }
        }
        
    }
    
    
    /**
     * 希尔排序
     *
     */
    public void xierSort(int []a,int d){            //执行排序
        while(d>=1){
            shellSort(a,d);
            d=d/2;
        }
    }
    
    public void shellSort(int []a,int d){            //一次希尔排序
        for(int i=d;i<a.length;i++){
            int j=i;
            while(j-d>=0){
                if(a[j]>a[j-d])
                    break;
                else{
                    int tmp=a[j];
                    a[j]=a[j-d];
                    a[j-d]=tmp;
                    j=j-d;
                }
            }
        }
    }
    
    
    /**
     * 冒泡排序(优化的冒泡排序)
     */
    public void pop(int []a){
        for(int j=a.length-2;j>=0;j--){
            int t=j;
        for(int i=0;i<=j;i++){             //一次冒泡排序            
            if(a[i]>a[i+1]){
                int tmp=a[i];
                a[i]=a[i+1];
                a[i+1]=tmp;
                t=i;
            }
        }
        j=t;
        }
    }                                                             
                                                                             
    
    /*
     *
     * 选择排序
     */
    public void selectSort(int []a){
        for(int j=a.length-1;j>0;j--){
        int d=0;
        for(int i=1;i<=j;i++)           //首先寻找最大值的位置
            if(a[i]>a[d])
                d=i;
            int tmp=a[j];               //将最大值放到有序曲
            a[j]=a[d];
            a[d]=tmp;
        }
    }
    
    
    /**
     * 堆排序
     */
    public void massSort(int []a){
        for(int j=a.length-1;j>0;j--){
            int tmp;
        for(int i=j;i>0;i--){                    //一次堆排序
            if(a[(i-1)/2]<a[i]){
                tmp=a[i];
                a[i]=a[(i-1)/2];
                a[(i-1)/2]=tmp;
            }
        }
        tmp=a[j];                         //对顶放到有序曲最后
        a[j]=a[0];
        a[0]=tmp;
        }
    }
    
    
    /**
     * 基数排序
     * 思路:将一位数用2进制表示,然后进行基数排序
     */
    public void baseSort(byte []a){
        
    }
    
    
    /*
     *思路:将两个有序的数组,归并为一个有序的数组                        //??????????????????
     * 归并排序                                                                                          //此算法有些问题
     */
    public void uninSort(int []a,int i,int j){
        int k=(i+j)/2;
        if(k!=i&&i<j)
            uninSort(a,i,k);
        if(j!=(k++)&&i<j)
            uninSort(a,k++,j);
        mege(a,i,k,k++,j);       
    }
    public void mege(int []a,int i,int j,int m,int n){                           //一次归并排序
        int []b=a;
        int t=i;
        while(i<=j&&m<=n){
            if(b[i]<=b[m]){
                a[t]=b[i];
                i++;
            }else{
                a[t]=b[m];
                m++;
            }    
            t++;
        }
        while(m<=n){
            a[t]=b[m];
            t++;
            m++;
        }
        while(i<=j){
            a[t]=b[i];
            t++;
            i++;
        }
    }

}



###########################################

8.*****************二分查找

9.***************数三游戏

package test2;
import java.util.Scanner;


public class TwoSearch {
    public static void main(String args[]){
        Scanner in=new Scanner(System.in);
        int []a=new int[8];
//        for(int i=0;i<8;i++)
//            a[i]=in.nextInt();
        TwoSearch ts=new TwoSearch();
//        System.out.println(ts.search(a, 9));
        PersonFirst first=new PersonFirst("陈");
        PersonFirst zero=first;
        for(int i=0;i<6;i++){
            PersonFirst tmp=new PersonFirst(in.nextLine());
            first.nextPersonFirst=tmp;
            first=tmp;
        }
        first.nextPersonFirst=zero;
        System.out.println(ts.lastPersonFirst(zero).name);
        System.out.println(ts.lastPersonFirst(zero).nextPersonFirst.name);
    }
    

    public int search(int []a,int x){        //二分查找必须是有序的
        int i=0;
        int j=a.length-1;
        int tmp = 0;
        while(i<=j){
            tmp=(i+j)/2;
            if(a[tmp]==x)
                 return tmp;
            else if(a[tmp]>x)
                j=tmp-1;
            else
                i=tmp+1;
        }
        if(i>j)
            tmp=-1;
        return tmp;
    }
    
    
    /**
     * 数三游戏
     */
    public PersonFirst lastPersonFirst(PersonFirst first){
        int i=1;      //计数     从第二个人开始计数
        while(!first.nextPersonFirst.name.equals(first.nextPersonFirst.nextPersonFirst.name)){
            if(i==3){
                PersonFirst tmp=first.nextPersonFirst;
                first.nextPersonFirst=tmp.nextPersonFirst;
                i=1;
                tmp=null;
            }else{
                i++;
                first=first.nextPersonFirst;
            }
        }    
        return first;
    }    
    
    /*
     * 两个有序合并  求合并后中间大的数
     * 两种思路
     * 1.排列
     * 2.1从中间找出两个数组的中位数a和b
     * 2.2判断a是否大于b[b的下标+1]或者b大于a[a的下标+1];但二者不同时成立
     * 2.3如果a大于b[b的下标+1]则,则将a的下标往下移动,b往上移动
     * 2.4如果b到头,则此时a为中位数;如果a到头b继续往下移动,知道移动到中位数的位置;
     */
//    public int middleSearch(int []a,int[]b){
//        //在数组面两部分合并后的最大值
//        int i=a.length;
//        int j=b.length;
//        int k=(i+j-1)/2;    //中间数位置
//        for(i=0;i)
//        
//    }
}

class PersonFirst{
    PersonFirst(String name){    //构造函数进行初始化
        this.name=name;
    }    
    String name;
    PersonFirst nextPersonFirst;      //相当于指针
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值