ReviewForJob(2)算法分析

【0】README
1)本文旨在review 算法分析的几个算法问题 附带源码;

【1】最大子序列和问题的解(两种解法——分治法+联机算法(推荐))
【1.1】分治法
1)intro:其思想是把问题分成两个大致相等的子问题,然后递归地对它们进行求解,这是“分”部分;“治”阶段 将两个子问题的 解合并到一起并可能再做些少量的附加工作,最后得到整个问题的解;
2)算法idea 描述:在我们的例子中(求最大子序列和的问题),最大子序列和可能出现在三个地方——或者整个出现在输入数据的左半部、或者整个出现在
右半部、或者跨越输入数据的中部从而占据左右两半部分;
3)如何求其解呢?  前两种情况,可以递归求解,第3种情况的最大和可以通过求出前半部分的最大和(包含前半部分的最后一个元素)以及 后半部分的最大  和(包含后半部分的第一个元素)而得到。然后将这两个和加在一起;


4)算法流程演示和源码如下:
#include<stdio.h>

#define ElementType int

int max3(int i, int j, int k)
{
    if(i < j)
	{
        i = j;
	}
    if(i < k)
	{
        i = k;
	}
    return i;
}

// compute the maximum sum of sebsequence.
// 3 in mxSubSum3 means 3 possibilities. 
int maxSubSum3(int A[], int left, int right)
{
	int onlyLeftSum, onlyRightSum; // just only left or right sum without center.
    int centerLeftSum, centerRightSum; // the 3rd is passing center.
    int tempSum;
    int center, i;
    
    if(left==right)
	{
        if(A[left] > 0)
		{
            return A[left];
		}
        else
		{
			return 0;
		}
	}
    center = (left+right)/2;  
    onlyLeftSum = maxSubSum3(A, left, center);
    onlyRightSum = maxSubSum3(A, center + 1, right);

    centerLeftSum = 0;    
    tempSum = 0;    
    for(i=center; i>=left; i--) 
	{   
        tempSum += A[i];
        if(tempSum > centerLeftSum)
		{
            centerLeftSum = tempSum;
		}
    }
    	
    centerRightSum = 0;
    tempSum = 0;
    for(i=center+1; i<=right; i++) 
	{ 
        tempSum += A[i];
        if(tempSum > centerRightSum)
		{
            centerRightSum = tempSum;
		}
    }
	printf("onlyLeftSum=%d, onlyRightSum=%d, centerLeftSum + centerRightSum=%d \n", onlyLeftSum, onlyRightSum, centerLeftSum + centerRightSum);
	return max3(onlyLeftSum, onlyRightSum, centerLeftSum + centerRightSum);  
} 

int main()
{
    int N = 8, maxSum = 0;            
    ElementType A[] = {4, -3, 5, -2, -1, 2, 6, -2};        
    
    maxSum = maxSubSum3(A, 0, N-1);        
    printf("the maximum sum of array {4, -3, 5, -2, -1, 2, 6, -2} is: %d \n", maxSum);    	    
}
【1.2】联机算法
1)intro:在任意时刻,算法对要操作的数据只需要读入一次,一旦被读入处理,它就不再需要被记忆了。而在处理过程中,算法对已读入的数据给出了正确的答案,具有这种特性的算法叫联机算法;
2)利用 联机算法求最大子序列和问题的解,源码如下(比 分治法效率高)
#include<stdio.h>

#define ElementType int

// 联机算法计算最大子序列和问题.
int maxSubSequenceSum(int A[], int N)
{
    int thisSum=0, maxSum=0;
	int j;    

    for(j = 0; j < N; j++) 
	{
        thisSum += A[j];
        if(thisSum > maxSum)
		{
            maxSum = thisSum;
		}
        else if(thisSum < 0)
		{
            thisSum = 0;
		}
    }
    return maxSum;
}

int main()
{
    int N = 8, maxSum = 0;            
    ElementType A[] = {4, -3, 5, -2, -1, 2, 6, -2};                    
    
	maxSum = maxSubSequenceSum(A, N);
    printf("the maximum sum of array  {4, -3, 5, -2, -1, 2, 6, -2} is %d \n", maxSum);    

    return 0;
}
【2】运行时间中的对数
【2.1】荔枝1——二分查找 
#include<stdio.h>

#define ElementType int
#define NOTFOUND -1

/* 二分查找,A[]升序排列 */
int binarySearch(ElementType A[], ElementType x, int N)
{
    int low, mid, high;

    low = 0;
    high = N - 1;

    while (low <= high)
	{
        mid = (low + high) / 2;
        if(A[mid] < x)
		{
            low = mid + 1;
		}
        else if(A[mid] > x)
		{
            high = mid - 1; 
		}
        else 
		{
			return mid;
		}
    }
    return NOTFOUND;
} 

main()
{
    int A[]={4, 5, 67, 67, 109, 876};
    int N=6, x=109;      	
	
	printf("\narray[] = {4, 5, 67, 67, 109, 876}");
    printf("\nthe position whose value equals to %d is %4d\n", x, binarySearch(A, x, N));
}
【2.1】荔枝2——计算最大公因数(欧几里得 算法)
#include<stdio.h>

#define ElementType int
#define NOTFOUND -1

/* 求两个数的最大公因数(greatest common divisor) */
int gcd(int M, int N)
{
    int rem;

    printf("remainder sequence: ");
    while (N > 0)
    {
        rem = M % N;
        M = N;
        N = rem;
        printf("%4d", rem);
    }
    return M;
}

main()
{
    int N = 1989, M = 1590;    
	int gcd_value;

	printf("\t\t\t ========== test for greatest common divisor ==========\n\n");    
    gcd_value = gcd(M, N);
    printf("\nthe greatest common divisor between %4d and %4d is %4d\n", M, N, gcd_value);

}
【2.1】荔枝3——高效率的幂运算
1)减少乘法次数:如 X^62 只用到了9次乘法:
X^3=(X^2)*X , X^7=(X^3)^2*X , X^15=(X^7)^2*X , X^31=(X^15)^2*X , X^62=(X^31)^2
2 + 2 + 2 + 2 + 1 == 9次; 
#include<stdio.h>

int isEven(int N)
{
	return N % 2 == 0 ? 1 : 0;
}

int pow(int x, int N)
{
    if(N == 0)
	{
        return 1;
	}
    else if(N == 1)
	{
        return x;
	}
    else if(isEven(N))    /* if(x) == if(N!=0) */
	{
		return pow(x * x, N / 2);
	}
    else
	{
		return pow(x * x, N / 2) * x;
	}
}

void main()
{
    int x = 2, N = 7;
    long pow_ = pow(x,N);
    printf("\t\t\t ========== test for computing pow  ==========\n");
	
    printf("\t\t\t result of %d^%d  is %-6d\n", x, N, pow_);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值