编程之美第二章

1、计算二进制数中1的个数: 

int num=0;

while(v)

{

    v&=(v-1);

    num++;

}

2、2.4. 1的数目

输入n,写出1到n的所有1的个数

#include<iostream>
using namespace std;
long long Sums(long long n)
{
    long long icount=0;
    long long ifactor=1;
    long long ilowernum=0;
    long long icurrnum=0;
    long long ihighernum=0;
    while(n/ifactor!=0)//从个位开始,像高位看
    {
        ilowernum=n-(n/ifactor)*ifactor;//低位数
        icurrnum=(n/ifactor)%10;//当前位
        ihighernum=n/(ifactor*10);//高位数
        switch(icurrnum)
        {
        case 0://当前位是0
            icount+=ihighernum*ifactor;
            break;
        case 1://当前位是1
            icount+=ihighernum*ifactor+ilowernum+1;//高位和低位
            break;
        default://当前位是其他
            icount+=(ihighernum+1)*ifactor;
            break;
        }
        ifactor*=10;
    }
    return icount;

}
int main()
{
    long long n;
    cin>>n;
    cout<<Sums(n)<<endl;
    return 0;
}

2.5 寻找最大的K个数

思路:堆排序。一遍搜索,找出K个最大的数,遇到比最小的大的插入,把最小的挤出去。最小堆。

2.6 精确表达浮点数

2.7 最大公约数问题

1、f(x,y)=f(y,x%y)

eg: f(42,30)=f(30,12)=f(12,6)=f(6,0)=6

2、f(x,y)=f(x-y,y)

3、x、y都是偶数,f(x,y)=2*f(x/2,y/2)

     x偶,y奇数,f(x,y)=f(x/2,y)

     x奇数,y偶,f(x,y)=f(x,y/2)

x,y均为奇数,f(x,y)=f(y,x-y)

2.8 找出符合条件的整数,没看懂。。。

任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0

#include<iostream>
#include<cstring> 
using namespace std;

int find_M(int N)
{
	//边界条件 
	if(N==1)
	  return 1;
	//初始化余数数组
	int *A=new int[N];//记录已有的余数 ,A[i]表示对N的余数为i的最小满足条件的数值 
	int *B=new int[N]; //记录更新的余数 
	memset(A,-1,N*sizeof(int));
	A[1]=1;
	//寻找过程
	int factor=10;//10,100,1000,.....
	bool not_found=true;
	while(not_found)
	{
		memset(B,-1,N*sizeof(int));
		int x=factor%N;//高位数值对N的余数
		cout<<"x "<<x<<"  ";
		cout<<"A[X]"<<A[x]<<endl;
		//高位数值+0的情况
		if(A[x]==-1)
		{
			
			B[x]=factor;
			cout<<"B[]X"<<B[x]<<endl;
			if(x==0)
			  break;
		 } 
		 //高位数值+低位正整数的情况
		 for(int i=1;i<N;i++)//遍历每个可能的余数 
		 {
		 	if(A[i]==-1)
		 	  continue;
		 	int new_x=(x+i)%N;//计算出的余数
		 	cout<<"new_x "<<new_x<<" x "<<x<<" i "<<i<<endl;
			if(A[new_x]==-1&&B[new_x]==-1)//如果是一个新的余数,保存
		    {
		    	B[new_x]=factor+A[i];	
		    		cout<<"new_x "<<new_x<<" "<<B[new_x]<<endl;
		    	if(new_x==0)//刚好找到的新的余数是0 
				{
					not_found=false;
					break;
					
				}
			}	
		
		  }
		  factor*=10;
		  for(int i=0;i<N;i++)
		  {
		  	if(A[i]==-1&&B[i]!=-1)
		  	   A[i]=B[i];
		   } 
	 }
	 int result=B[0];
	 delete[]A;
	 delete[]B;
	 return result; 
 } 
 int main()
 {
 	int N;
 	while(true)
 	{
 		cout<<"N:";
 		cin>>N;
 		if(N<1)
 		  break;
 		  cout<<"M:"<<find_M(N)/N<<endl;
 		  cout<<"正整数为:"<<find_M(N)/N*N<<endl;
 		  
	 }
	 return 0;
 }
 
 
 
 
 
 
 

测试过程,如输入6

N=6的计算过程
factor=10
x=4 A[x]=-1  所以,B[X]=10

for循环
   i=1,new_x=5;
   B[5]=11
   A[5]=11

facotr=100;
  A[4]=B[4]=10;


B清空
x=100%6=4
for循环中:
   new_x=(4+4)%6=2;
   B[2]=100+10=110;


   new_x=(4+5)%6=3;
   B[3]=100+11=111

factor=1000
   A[2]=B[2]=110

B清空
    x=1000%6=4
for循环
   new_x=(4+2)%6=0;
   B[0]=1110;
直接跳出

2.10 寻找数组中最大值和最小值

分治思想

(int max,int min)Search(int arr[],int b,int e)
{
   if(e-b<=1)//不是最后一个数
   {
       if(arr[b]<arr[e])
          return (arr[e],arr[b]);
       else
          return (arr[b],arr[e]);
   }
int maxL,minL,maxR,minR,minV,maxV;
   (maxL,minL)=Search(arr,b,b+(e-b)/2);
   (maxR,minR)=Search(arr,b+(e-b)/2+1,e);
if(maxL>maxR)
   maxV=maxL;
else
   maxV=maxR;
if(minL<minR)
  minV=minL;
else
   minV=minR;
return (maxV,minV);


}

一共需要比较 1.5N-2次。

2.12快速寻找满足条件的两个数,两个数的和等于一个给定的值

 首先,排序,时间复杂度:Nlog2N.然后两个指针,前一个后一个,两数之和<x,i++,>x,j–.

(int i,int j) find(int arr[],int n,int x)
{
	int i=0,j=n--;
	while(i<j)
	{
		if(arr[i]+arr[j]==x)
		return (i,j);
		else if(arr[i]+arr[j]<x)
		  i++;
		else
		 j--;
	}
	return (-1,-1);
	
 } 

2.13子数组的最大乘积,N-1个数的最大乘积

设N个数的乘积是P

若p==0,则至少有一个0,把0删去,讨论剩下所有数乘积的正负:若为负数,则得0,若为正数,则为该正数

若p<0,则负数个数是奇数,除去一个负数,则是正数,一定最大。

若p>0,如果存在正数,去掉一个最小的正数,否则去掉一个绝对值最大的负数,反正都是去掉一个最小的数。

2.14  和最大的连续子数组

从后往前遍历

int max(int x,int y)
 {
 	return (x>y)?x:y;
 }
 int maxSum(int *A,int n)
 {
 	nstart=A[n-1];
 	nall=A[n-1];
 	for(i=n-2;i>=0;i--)
 	{
 		nstart=max(A[i],nall+A[i]);
 		nall=max(nstart,nall);
	 }
 }

    原文作者:little_ppj
    原文地址: https://blog.csdn.net/feng_xinlei/article/details/80986897
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞