笔试练习五

1.把一个数组最开始的若干个元素搬到素组的末尾,我们称之为数组的旋转。输入一个递增的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2} 为{1,2,3,4,5}的一个旋转,找出该数组中的最小数也就是1。

分析:首先肯定会想到直接一个一个进行比较不是就可以了吗,但是细心的人会注意到这个题目中特别突出的就是一个递增的词语,这说明这个数组一开始是有序的,尽管进行了旋转也就是有点循环移位的意思,但是大部分肯定还是有序的,再经过分析,是最多两部分基本有序,有时候还是直接就是原数组有序,这就让我们这个猿猴们想到了用二分查找的方法,从基本的O(n)---------->O(logn)

下图是{4,5,1,2,3} 进行查找的一个步骤图:

具体的实现代码如下:

int find_min_from_array(int array[],int length)
{
  if(array == 0 || length <=0)
  {
    return -1;
  }
  int left = 0;
  int right = length-1;
  int mid = left;

  while(array[left] >= array[right])
    { 
        if(right - left == 1)
        {
         mid = right;
         break;
        }
        mid = left +((right-left)>>1);
        if(array[mid] == array[left] && array[mid] == array[right])
        {
            mid =0;
         for(int i=1;i<length;++i)
         {
             if(array[i] < array[mid])
             {
                mid = i;
             }
         }
         break;
        }
        if(array[mid] >= array[right])
        {
          left = mid;
        }
        else if(array[mid] <= array[right])
        {
           right = mid;
        }
    
    }
  return mid;
}

int main()
{

//int array[]={4,5,1,2,3};
int array[]={1,0,1,1,1};  //当出现这种最左边和最右边还有中间数据相等的情况,这个时候只能进行正常的查找
cout<<find_min_from_array(array,5)<<endl;

  return 0;
}
2.求斐波那契数的第N项的值


底下是递归和非递归的实现:

//递归实现
int  Recur_Fibonacci(int n)
{
  if(n<0)
  {
  return -1;
  }
  if(n==0 || n== 1)
   {
   return n;
   }
    return (Recur_Fibonacci(n-1)+Recur_Fibonacci(n-2));
}

//非递归实现
int Loop_Fibonacci(int n)
{
    if(n<0)
	{
    return -1 ;
    }
   if(n==0 || n== 1)
    {
     return n;
    }
     int f1=0;
	 int f2=1;
	 int f3=0;
	 while(n>=2)
	 {
	       f3=f1+f2;
	       f1=f2;
		   f2=f3;
		   --n;
	 }
	 return f3;

}
int main()
{
cout<<Loop_Fibonacci(6)<<endl;

return 0;
}
3.求二进制中1的个数
首先我们会想到直接从数据的最左边开始进行&1就可以取出第一个位的数据 ,再进行计算,所以就出现了底下的代码

int Number_Of_One(int n)
{
  int count=0;
  while(n)
	{
      if(n & 1)
		{
	     count++;
	    }
		n>>=1;//但是这种出现负数的时候移位就会引起数据的变化,因为负数是左移高位补符号
  }
  return count;
}
就如上边说的如果是负数会出现问题
所以我们要想到另一种做法
int Number_Of_One(int n)
{
     int count = 0;
	 while(n)  //当n的所有位全部变成0的时候结束
	{
	 count++;
	 n &= (n-1); //n-1的使得最后一个位1变成了0
	 }
     return count;
}

//扩展:求零的个数
int Number_Of_Zero(int n)
{
    int count=0;
	while(n+1)//当n的所有位全变成1的时候再加一就是0了
	{
	 count++;

	 n |= (n+1);//n+1将n的最后一个位0变成了1
	}
    return count;
}

int main()
{
   cout<<Number_Of_One(15)<<endl;
    cout<<Number_Of_Zero(15)<<endl;
  return 0;
}
4.

//求数值的整数次方
double Power(double num,int n )
{
	if((num>-0.0000001 && num < 0.0000001))
	   {
	     return 0.0; 
	   }
      if(n == 0)
	   {
	   return 1.0;
	   }
	   if(n < 0)
	   {
	    n=-n;
	   }
	   double result=1.0;
	   while(n)
	    {
	      result *= num;
		  --n;
	   }
	   if(n < 0)
	   {
	    result=1.0/result;
	   }
	  return result;
}

int main()
{

cout<<Power(0,1)<<endl;
return 0;

}
5.打印 1到-----N个数字组成的最大数

bool  Increment(char *number,int n)
{
	bool ret = false;
    int ntakeover = 0;
    for(int i=n-1;i>=0;--i)
	   {
	   int sum = number[i]-'0'+ntakeover; 
	     if(i == n-1) //个位数字加一
		   {
		   sum++;
		   }
	   if(sum==10) //个位加1之后等于10的时候。这样加一上来只能等于10
		   {
		       if(i==0) //如果此时最高位加一位10 的时候那就是最大数的时候,此时终止
			   {
                ret = true;
		       }
	           else
			   {
			   sum -= 10; 
               ntakeover=1; //进一位
			   number[i]='0'+sum; //个位赋值
			   }
	       }
		else //个位加一之后没有10大的
		   {
		     number[i]='0'+sum;
			 break;
		   }
	   }
         return ret;
}

void PrintNumber(char *number,int n)
{
	bool begin=true; //begin用于控制输出类似于10 20 后边的零
   for(int i=0;i<n;++i)
	{
     if(begin && number[i] != '0')
		{
	   begin=false;
	     }
		 if(!begin)
		{
		  cout<<number[i];
		 }
    }

}

void Print1ToMaxOfNdigit(int n)
{
  if(n <=0 )
	{
   return ;
    }
   char *number= new char[n+1];
   memset(number,'0',n);
   number[n]='\0';
   
   while(!Increment(number,n)) //每次循环进去执行
	{
     PrintNumber(number,n);
	 cout<<" ";
    }
	cout<<endl;
    
    delete []number;

}

int main()
{

Print1ToMaxOfNdigit(2); 

return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值