package com.raisecom.tiap.ems.basic.mgt.domain.acl;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class recursionInfo {
public static void main(String[] args) {
//System.out.println(1<<35);
//System.out.println(1<<3);
recursionInfo a = new recursionInfo();
a.swap(5,10);
//testInfo.placeOneOrZero(2,2);
//a.findRepeatNum();
//a.conutOne();
//a.doubleBinary();
// a.korOneCount();
// a.printHanoiTower(3,"A","B","C");
int [] arr = {7,6,5,4,3,2,1,100,99,7};
//a.shellSort(arr);
//testInfo.print(arr);
//int b = a.binarySearch(arr,0,arr.length-1,100);
//System.out.println(b);
String [] str = {"a","","ac","","ad","b","","ba"};
int res = a.indexOf(str,"baa");
System.out.println(res);
}
public static void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
public static void print(int [] a)
{
System.out.println(Arrays.toString(a));
}
public void swap(int a, int b)
{
a = a^b;
b = a^b;
a= a^b;
//System.out.println("交换后 a="+a+" b="+b);
}
/**
* 递归设计经验
* 找重复(子问题)
* 找重复中的变化量---参数
* 找参数变化趋势---设计出口
* 策略 直接量+小规模子问题和多个子规模问题变种
* 或者可以对于数学问题找递推公式或者是等价转换
* 循环改递归
* 经典递归
* 大量练习,总结规律,找套路
*
*
*/
//求一个数的阶乘
public int factorial(int n)
{
if (n==1){ //注意没有0的阶乘
return 1;
}
else
{
return n*factorial(n-1);
}
}
//打印i到j,i小于j(用for循环但是需要递归)
public void f1(int i, int j)
{
if (i>j) //出口
return;
System.out.println(i); //i为变化量
f1(i+1,j);//重复
}
//打印数组元素
public int f2(int [] arr, int begin) //加参数进行出界口,递归的妙用
{
if (begin==arr.length-1)
return arr[begin];
return arr[begin] + f2(arr,begin+1);
}
//反转字符串 切的量在变,设计成参数
public String reverse(String src,int end){
if (end ==0)
{
return ""+src.charAt(0);
}
return src.charAt(end)+reverse(src,end-1);
}
//斐波那契数列 fn = fn-1+fn-2 n=1 或者n=2的为1 调用过程是先纵后横,先挖深再兄弟
//对于最大公约数的球阀,可以用辗转相除法
public int gcd(int m, int n)
{
if (n==0)
return m;
return gcd(n,m%n);//辗转相除法
}
//插入排序用递归法:找到等价方式,前n-1个元素排好序,最后一个插入到以前的
public void insertSort(int [] arr, int k)
{
if (k==0)
{
return;
}
//对前k-1个元素排序
insertSort(arr, k-1);
//把位置k的元素插入到前面部分
int x = arr[k];
int index = k-1;
while(index >-1&&x<arr[index])
{
arr[index+1]=arr[index];
index--;
}
arr[index+1] =x;
}
/*
汉诺塔问题,将1-N从A移动到C,B为中转。
思路1 1-N-1 移动到C,B为辅助,N从A移动到B,再把
1-N从C移动到B,A为辅助。这是一个等价问题
@param N 初始的N个从小到大的盘子,N为大的编号
@param from 原始柱子
@param to 目标柱子
@param help 辅助柱子
*/
public void printHanoiTower(int N, String from, String to, String help)
{
if (N==1) //边界
{
System.out.println("move " +N +" from "+from +" to " +to);
return;
}
printHanoiTower(N-1,from,help,to);//转换角色
System.out.println("move " +N +" from "+from +" to " +to);
printHanoiTower(N-1,help,to,from);
}
/**
* 二分查找的递归问题
* 思路全范围二分查找等价于三个子问题:
* 左边找递归
* 中间比
* 右边查找递归 注意:左边查找和右边查找只选其一
*/
public int binarySearch(int[] arr, int low, int high, int key)
{
if (key<arr[low]||low > high|| key>arr[high]) //边界条件
return -1;
int mid = low+((high-low)>>1);
int midVal = arr[mid];
if (midVal<key)
return binarySearch(arr, mid+1,high,key);
else if (midVal>key)
return binarySearch(arr,low,mid-1,key);
else
return mid;
}
/**冒泡(交换),插入(挪动数组),选择(最大最小),
* 希尔排序是一种插入排序,是称为缩小增量排序
*思路:一趟一个增量,用增量来分组,组内执行插入排序
*
*/
public void shellSort(int [] arr)
{
for (int interval = arr.length/2; interval>0;interval=interval/2)
{
for (int i =interval; i<arr.length;i++) {
int target = arr[i];
int j = i - interval;
while (j > -1 && target < arr[j]) {
arr[j + interval] = arr[j];
j-=interval;
}
arr[j + interval] = target;
}
}
}
/**小白上楼梯,有n阶楼梯,一次可以上1阶,2阶,或者3阶,
* 小白有多少种方法走完楼梯
* 思路:用递归
*
*/
public int walkCount(int n){
if (n==0) return 1;//这个有点牵强
if (n==1) return 1;
if (n==2) return 2;//注意这个容易出错
return walkCount(n-1)+walkCount(n-2)+walkCount(n-3);//这个和斐波那契数列想法一样?
}
/**旋转数组的最小数字
* 把一个数组最开始的若干个元素搬到数组末尾,
* 输入一个递增排序的数组的一个旋转,输出旋转数组最小元素。
*思路:有序性代表的就是二分查找,从中间划一刀分为左右两部分
* 12345----34512旋转后数组,最小值是在无序数组的一侧,再划
* 切分,最终切分成两个元素就找到了
*/
public int minValue(int [] arr)
{
int begin = 0;
int end = arr.length -1;
//考虑没有旋转特殊情况
if (arr[begin]<arr[end])
return arr[begin];
while(begin +1 <end)
{
int mid = begin + ((end-begin)>>1); //注意数组的特殊情况{01111}
if (arr[mid]>=arr[begin]){ //左侧有序
begin=end;
}else {
end = mid;
}
}
return arr[end];
}
/**
* 有空字符串的有序字符数组中查找,找出给定字符串的索引
*思路:
*/
public int indexOf(String [] str, String p)
{
int begin = 0;
int end = str.length-1;
while (begin<=end)
{
int midIndex = begin + ((end-begin)>>1);//注意放到循环外边的话,死循环
while (str[midIndex].equals("")){
midIndex++;
if (midIndex >end) //防止死循环一直走空串其它
return -1;
}
if (str[midIndex].compareTo(p)>0)
{
end = midIndex-1;
}
else if (str[midIndex].compareTo(p)<0)
{
begin = midIndex+1;
}
else
{
return midIndex;
}
}
return -1;
}
}