《编程之美——微软技术面试心得》勘误表(转自http://blog.csdn.net/justpub/article/details/2378778#comments)

 

1.       第7页,第2行

原文:不过我们还是不能简单地将n=60000000

修订:不过我们还是不能简单地将n=960000000

 

2.       第16页,第13行

原文:10100000>>4=00000101

修订:10100000>>4=00001010

 

3.       第19页,倒数第4行

原文:if(i.a % 3 == i.b%3)

修订:if(i.a % 3 != i.b%3)

 

4.       第9页

原文:代码清单1-3

// C# code

static void MakeUsage(float level)

{

     PerformanceCounter p = new PerformanceCounter("Processor","% Processor

       Time", "_Total");     

 

     while(true)

     {

          if(p.NextValue() > level)

               System.Threading.Thread.Sleep(10);

     }

}

修订为:

// C# code

static void MakeUsage(float level)

{

     PerformanceCounter p = new PerformanceCounter("Processor",

       "%Processor Time", "_Total");     

 

     if(p==NULL)

     {

          Return;

     }

 

     while(true)

     {

          if(p.NextValue() > level)

               System.Threading.Thread.Sleep(10);

     }

}

 

5.       第19页,代码清单1-7

原文:

struct {

       unsigned char a:4;

       unsigned char b:4;

} i;

 

for(i.a = 1; i.a <= 9; i.a++)

for(i.b = 1; i.b <= 9; i.b++)

       if(i.a % 3 == i.b % 3)

                     printf(“A = %d, B = %d/n”, i.a, i.b);

 

修订为:

struct {

       unsigned char a:4;

       unsigned char b:4;

} i;

 

for(i.a = 1; i.a <= 9; i.a++)

    for(i.b = 1; i.b <= 9; i.b++)

       if(i.a % 3!= i.b % 3)

             printf(“A = %d, B = %d/n”, i.a, i.b);

 

 

6.       第23页,代码清单1-8中11-15行:

原文:

       CPrefixSorting()

         {

                   m_nCakeCnt = 0;

                   m_nMaxSwap = 0;

         }

 

修订为:

CPrefixSorting()    

     {

          m_nCakeCnt = 0;

          m_nMaxSwap = 0;

     }

 

    ~CPrefixSorting()

    {

          if( m_CakeArray != NULL )

          {

               delete m_CakeArray; 

          }

          if( m_SwapArray != NULL )

          {

               delete m_SwapArray; 

          }

          if( m_ReverseCakeArray != NULL )

          {

               delete m_ReverseCakeArray; 

          }

          if( m_ReverseCakeArraySwap != NULL )

          {

               delete m_ReverseCakeArraySwap; 

          }

     }

 

7.       第24页,第10行

原文:m_nCakeCnt = n;

修订:m_nCakeCnt = nCakeCnt;

 

 

8.       第24页,第22行

原文:m_SwapArray = new int[m_nMaxSwap];

修订:m_SwapArray = new int[m_nMaxSwap + 1];

 

9.       第27页,第12行

原文:nEstimate = LowerBound(m_tArr, m_n);

修订:nEstimate = LowerBound(m_ReverseCakeArray, m_n);

 

10.   第27页,第17行

原文:在到达m_tArr状态之前,我们已经翻转了step次

修订:在到达m_ReverseCakeArray状态之前,我们已经翻转了step次

 

11.   第32页,第10行~第11行(即第4段):

原文:根据题意,只要是不同卷的书组合起来就能享受折扣,至于具体是哪几卷,并不要求。因此,就可以不用考虑其他可能比如(Y1-1, Y2-1, Y3-1, Y4Y5-1)。

修订:根据题意,不同卷的书组合起来才能享受折扣,至于具体是哪几卷,并没有要求。因为(Y1-1, Y2-1, Y3-1, Y4-1, Y5)能够保证在选择当前折扣情况下,剩下的书种类最多,它比其他组合都好。我们不用再考虑其他可能,如(Y1-1, Y2-1, Y3-1, Y4Y5-1)。

 

12.   第34页,倒数第5行

原文:

假设这样的分法存在,那么就可以按照小于10的情况考虑求解。如果要买的书为(Y1Y2Y3Y4Y5)(其中Y1>=Y2>=Y3>=Y4>=Y5),贪心策略建议我们买Y5本五卷的,Y4Y5本四卷,Y3-Y4本三卷,Y2-Y3本两卷和Y1-Y2本一卷。由于贪心策略的反例,我们把K本五卷和K本三卷重新组合成2×K本四卷(K = min{Y5Y3-Y4})。结果就是我们买Y5-K本五卷的,Y4-Y5本四卷,Y3-Y4-K本三卷,Y2-Y3本两卷和Y1-Y2本一卷(K = min{Y5Y3-Y4})。

 

修订:

假设这样的分法存在,那么就可以按照小于10的情况考虑求解。如果要买的书为(Y1Y2Y3Y4Y5)(其中Y1>=Y2>=Y3>=Y4>=Y5),贪心策略建议我们买Y5本五卷的,Y4Y5本四卷,Y3-Y4本三卷,Y2-Y3本两卷和Y1-Y2本一卷。由于贪心策略的反例,我们把K本五卷和K本三卷重新组合成2×K本四卷(K = min{Y5Y3-Y4})。结果就是我们买Y5-K本五卷的,Y4-Y5+2K本四卷,Y3-Y4-K本三卷,Y2-Y3本两卷和Y1-Y2本一卷(K = min{Y5Y3-Y4})。

 

13.   第36页的第5行~第6行:

原文:假设有n个ID,这个解法占用的时间复杂度为O(N

应为:假设有N个ID,且ID的取值在0-(N-1)之间,这个解法占用的时间复杂度为O(N

 

14.   第36页的倒数第8行~第10行:

原文:

具体方法如下:遍历列表,利用变长数组记下每个ID出现的次数,每次遇见一个ID,就向变长数组中增加一个元素;如果这个ID出现的次数为2,那么就从变长数组中删除这个ID,最后变长数组中剩下的ID就是我们想要的结果。

应为:

具体方法如下:遍历列表,利用哈希表记下每个ID出现的次数,每次遇见一个ID,就向哈希表中增加一个元素;如果这个ID出现的次数为2,那么就从哈希表中删除这个ID,最后哈希表中剩下的ID就是我们想要的结果。

 

15. 第41页,第6行

原文:最大数量指如果仅买某种饮料的最大可能数量,比如对于第i中饮料Ci=V/Vi

修订:最大数量指STC存货的上限。

 

16. 第41页,第13行

原文:因此,Opt(Vn)就是我们要求的值。

修订:因此,Opt(V,0)就是我们要求的值

 

17. 第41页,倒数第10行

原文:用Opt(V'i)表示从第ii+1, i+2,…, n-1, n种饮料中,算出总量为V'的方案中满意度之和的最大值。

修订:用Opt(V'i)表示从第ii+1, i+2,…, n-1种饮料中,算出总量为V'的方案中满意度之和的最大值。

 

18. 第41页,倒数第8行

原文:Opt (V'i) = max { kHi + Opt(V' - Vi * ki-1)}

修订:Opt (V'i) = max { kHi + Opt(V' - Vi * ki+1)}

 

19. 第41页,倒数第6行

原文:

最优化的结果 = 选择第k种饮料*满意度 + 减去第k种饮料*容量的最优化结果

修订:

最优化的结果 = 选择k个第i种饮料的满意度 + 剩下部分不考虑第i种饮料的最优化结果的最大值。

 

20. 第42页,第3行

原文:int Cal(int V, int type)

修订:int Cal(int V, int T)

 

21. 第42页,第5行

原文://边界条件

修订://边界条件,T为所有饮料种类

 

22. 第42页的倒数第1行:

原文:所以空间复杂度可以降为Ov)。

修订:所以空间复杂度可以降为OV)。

 

23. 第42页的第16行:

原文:if ( i<=k*V[j] )

修订:if ( i < k*V[j] )

 

 

24. 第51页

代码清单1-11

int nPerson[];               // nPerson[i]表示到第i层的乘客数目

int nFloor, nMinFloor, nTargetFloor;

nTargetFloor = -1;

for(i = 1; i <= N; i++)

{

         nFloor = 0;

         for(j = 1; j < i; j++)

                   nFloor += nPerson[j] * (i - j);

         for(j = i + 1; j <= N; j++)

                   nFloor += nPerson[j] *(j - i);

         if(nTargetFloor == -1 || nMinFloor > nFloor)

         {

                  nMinFloor = nFloor;

                  nTargetFloor = i;

         }

}

return(nTargetFloor, nMinFloor);

修订:

int nPerson[];               // nPerson[i]表示到第i层的乘客数目

int nFloor, nMinFloor, nTargetFloor;

nTargetFloor = -1;

for(i = 1; i <= N; i++)

{

    nFloor = 0;   

    for(j = 1; j < i; j++)

         nFloor += nPerson[j] * (i - j);

    for(j = i + 1; j <= N; j++)

         nFloor += nPerson[j] *(j - i);

    if(nTargetFloor == -1 || nMinFloor > nFloor)

    {

         nMinFloor = nFloor;

         nTargetFloor = i;

    }

}

return(nTargetFloor, nMinFloor);

 

25. 第56页,第9行

原文:E[i]为面议结束时间

修订:E[i]为面试结束时间

 

26. 第57页,第19行

原文:Break;

修订:break;

 

 

27. 第67页,倒数第2行

原文:(大于1)个石头

修订:(大于0)个石头

 

28. 第78页,倒数第13行

原文:if(m-n == (long)floor(n*a)){ return false};

修订:if( n == (long)floor((m-n)*a) ){ return false;}

 

29. 第79页,倒数第6行

原文:Bn={b1,b2,bn}

修订:Bn={b1,b2,…,bn}

 

30. 第79页,倒数第3行

原文:n为除0以外

修订:N为除0以外

 

31. 第79页,倒数第2行

原文:an<an+1

修订:an<an+1

 

32. 第80页,倒数第10行

原文:只能到达不安全局面

修订:只能到达安全局面

 

33. 第81页,第10行

原文:1/a + a/b = 1;

修订:1/a + 1/b = 1;

 

34. 第82页

原文:判断y-x(假设x<=y)是否等于[a]*(y-x)来判断

修订:判断x(假设x<=y)是否等于[a]*(y-x)来判断

 

 

35.   第101页,倒数第10行

原文:转化为小数的问题

修订:转化为分数的问题

 

36.   第104页,倒数第2行

原文:所有非空真子集个数为2n-2

修订:所有非空真子集个数为2n-2

 

37.   第104页,倒数第1行

原文:(2n-2 )/2个Fork函数

修订:(2n-2)/2个Fork函数

 

38.   第106页,第5行

原文:范围从1到2n-2(n=4)

修订:范围从1到2n-2(n=4)

 

39.   第106页,第6行

原文:再用一个大小为2n-1(n=4)

修订:再用一个大小为2n-1(n=4)

 

40.   第106页,第7行

原文:其中S[2n-1]即为集合

修订:其中S[2n-1]即为集合

 

41.   第106页,第8行

原文:通过检查S[2n-1],

修订:通过检查S[2n-1],

 

 

42.   第121页,代码2-2

原文:

代码清单2-2

int Count(int v)

{

         int num = 0;

         While(v)

         {

                   num += v &0x01;

                   v >>= 1;

         }

         return num;

}

修订:

代码清单2-2

int Count(BYTE v)

{

         int num = 0;

         while(v)

         {

                   num += v & 0x01;

                   v >>= 1;

         }

         return num;

}

 

43.   第122页,代码2-3

原文:int Count(int v)

修订:int Count(BYTE v)

 

44.   第122页,代码2-4

原文:int Count(int v)

修订:int Count(BYTE v)

 

45.   第122页,代码2-5

原文:int Count(int v)

修订:int Count(BYTE v)

 

46.   第126页,第5行

原文:N!=(2x)*(3y)*(5z

修订:N!=(2X)*(3Y)*(5Z

 

47.   第128页,第6行,问题2的解法二中

原文:N=11011

修订:N=11011(二进制表示, 下列01串均为整数的二进制表示)

 

48.   第133页,倒数第1行

原文:增大而线性增长。

修订:增大而以超过线性的速度增长。

 

49.   第135页,倒数第5行

原文:等于低位数字(123)+1。

修订:等于低位数字(113)+1。

 

50.   第137页,第11行

原文:f(10n-1)= * 10n-1

修订:f(10n-1) = n * 10n-1

 

51.   第137页:

原文:容易从上面的式子归纳出:f(10n-1)= n * 10n-1。通过这个递推式,很容易看到,当n = 9时,fn)的开始值大于n

修订:容易从上面的式子归纳出:f(10n-1)= * 10n-1。通过这个递推式,很容易看到,当n=1010-1时,fn)的值大于n

 

52.   第137至138页,倒数第13行

原文:

首先,当k>=10时,k*10 k-1> 10 k,所以fn)的增加量大于n的增加量。

其次,f(1010-1)=1010>1010-1。如果存在N,当n = N时,fN)-N>1010-1成立时,此时不管n增加多少,fn)的值将始终大于n

具体来说,设n的增加量为m:当m小于1010-1时,由于fN)-N>1010-1,因此有fN + m)> fN)> N + 1010-1 N + m,即fn)的值仍然比n的值大;当m大于等于1010-1时,fn)的增量始终比n的增量大,即fN + m)- fN)>(N+m)- N,也就是fm)> fN)+ m > N + 1010-1m > N +m,即fn)的值仍然比n的值大。

因此,对于满足fN)- N > 1010-1成立的N一定是所求该数的一个上界。

求出上界N

又由于f(10k-1) = k * 10k-1,不妨设N=10k-1,有f(10k-1)-(10K-1) > 1010-1,即k*10 k-1 -(10 k-1)> 1010-1,易得k > =11时均满足。所以,当k = 11时,N=1011-1即为最小一个上界。

修订:

n按十进制展开,n=a*10k+b*10k-1+…,则由上可得,

fn)=f(0+ a*10k+b*10k-1+……)>a* k*10k-1+b*(k-1)*10k-2

这里把a*10k看作在初值0上作a次的10k的增量,b*10k-1为再作b次的10k-1的增量,重复使用上面关于自变量的10k增加量的归纳结果。

又,

=a*10k+b*10k-1+…< a*10k+(b+1)*10k-1

如果ak*10k-1+b*(k-1)*10k-2 >= a*10k+(b+1)*10k-1的话,那么fn)必然大于n。而要使不等式ak*10k-1+b*(k-1)*10k-2 >= a*10k+(b+1)*10k-1成立,k需要满足条件:>= 10 +(b + 10)/(b + 10*a)。显然,当k > 11,或者说n的整数位数大于等于12时,fn)> n恒成立。因此,我们求得一个满足条件的上界N=1011

 

53.   第138页,倒数第9行

原文:N = 1010-1 = 99 999 999 999

修订:N = 1010-1 = 99 999 999 999

 

54.   第141页,代码2-11

原文:

代码清单2-11

Kbig(S, k):

         if(k <= 0):

                   return []               // 返回空数组

         if(length S <= k):

                   return S

         (Sa, Sb) = Partition(S)

         return Kbig(Sa, k).Append(Kbig(Sb, k – length Sa)

 

Partition(S):

         Sa = []                                    // 初始化为空数组

         Sb = []                                    // 初始化为空数组

                                                        // 随机选择一个数作为分组标准,以避免特殊数据下的算法退化

                                                        // 也可以通过对整个数据进行洗牌预处理实现这个目的

                                                        // Swap(S[1], S[Random() % length S])

p = S[1]

         for i in [2: length S]:

                   S[i] > p ? Sa.Append(S[i]) : Sb.Append(S[i])

                                                        // 将p加入较小的组,可以避免分组失败,也使分组更均匀,提高效率

length Sa < length Sb ? Sa.Append(p) : Sb.Append(p)

return (Sa, Sb)

 

修订:

代码清单2-11

Partition(S):

     Sa = []                                                       // 初始化为空数组

     Sb = []                                                        // 初始化为空数组

     Swap(s[1], S[Random()%length S])                                         // 随机选择一个数作为分组标准,以

                                                                                                  // 避免特殊数据下的算法退化,也可

                                                                                                   // 以通过对整个数据进行洗牌预处理

                                                                                                   // 实现这个目的

     p = S[1]

     for i in [2: length S]:

         S[i] > p ? Sa.Append(S[i]) : Sb.Append(S[i])

                                                             // 将p加入较小的组,可以避免分组失败,也使分组

                                                             // 更均匀,提高效率

length Sa < length Sb ? Sa.Append(p) : Sb.Append(p)

return (Sa, Sb)

 

 

55.   第148页,倒数第9行

原文:Y=0.b1b2bm

修订:Y=0.(b1b2bm

 

56.   第153页,第12,13行

原文:fxy) = fxx – y

修订:fxy) = fy y

 

57.   第158页,代码2-17

原文:

代码清单2-17

// 初始化

         for(i = 0; i < N; i++)

                   BigInt[i].clear();

         BigInt[1].push_back(0);

 

         for(i = 1, j = 10 % N; ;i++, j = (j * 10) % N)

         {

                   int NoUpdate = 0;

                   bool flag = false;

                   if(BigInt[j].size() == 0)

                   {

                            // BigInt[j] = 10^i, (10^i % N = j)

                            BigInt[j].clear();

                            BigInt[j].push_back(i);

                   }

                   for(k = 1; k < N; k++)

                   {

                            if((BigInt[k].size() > 0)

                                     && (i > BigInt[k][BigInt[k].size() - 1])

                                     && (BigInt[(k + j) % N].size() == 0))

                            {

                                     // BigInt[(k + j) % N] = 10^i + BigInt[k]

                                     flag = true;

                                     BigInt[(k + j) % N] = BigInt[k];

                                     BigInt[(k + j) % N].push_back(i);

                            }

                   }

                   if(flag == false)

                            NoUpdate++;

                   // 如果经过一个循环节都没能对BigInt进行更新,就是无解,跳出。

                   // 或者BigInt[0] != NULL,已经找到解,也跳出。

                   if(NoUpdate == N || BigInt[0].size() > 0)

                            break;

         }

         if(BigInt[0].size() == 0)

         {

                   // M not exist

         }

         else

         {

                   // Find N * M = BigInt[0]

         }

修订:

代码清单2-17

// 初始化

         for(i = 0; i < N; i++)

                   BigInt[i].clear();

         BigInt[1].push_back(0);

int NoUpdate = 0;

         for(i = 1, j = 10 % N; ;i++, j = (j * 10) % N)

         {                

                   bool flag = false;

                   if(BigInt[j].size() == 0)

                   {

flag = true;

                            // BigInt[j] = 10^i, (10^i % N = j)

                            BigInt[j].clear();

                            BigInt[j].push_back(i);

                   }

                   for(k = 1; k < N; k++)

                   {

                            if((BigInt[k].size() > 0)

                                     && (i > BigInt[k][BigInt[k].size() - 1])

                                     && (BigInt[(k + j) % N].size() == 0))

                            {

                                     // BigInt[(k + j) % N] = 10^i + BigInt[k]

                                     flag = true;

                                     BigInt[(k + j) % N] = BigInt[k];

                                     BigInt[(k + j) % N].push_back(i);

                            }

                   }

                   if(flag == false)NoUpdate++;

else NoUpdate=0;

                   // 如果经过一个循环节都没能对BigInt进行更新,就是无解,跳出。

                   // 或者BigInt[0] != NULL,已经找到解,也跳出。

                   if(NoUpdate == N || BigInt[0].size() > 0)

                            break;

         }

         if(BigInt[0].size() == 0)

         {

                   // M not exist

         }

         else

         {

                   // Find N * M = BigInt[0]

         }

 

58.   第163页,倒数第11行

原文:An=A * A *…* A

修订:An=A * A *…* A

 

59.   第165页倒数第1行:

原文:对于n非常大的情况,如n=260的时候,如何计算An)呢?

修订:对于n非常大的情况,如n=260的时候,如何计算An)mod M(M < 100000)呢?

 

60.   第178页,倒数第1行

原文:这个数组中肯定存在这样一组或以上符合要求的解

修订:这个数组中肯定存在至少一组符合要求的解

 

61.   第190页,倒数第2行

原文:i > j

修订:i <= j

 

62.   第209页的第8行~第10行:

原文:

从有效性来分析,整个代码是一个三重循环,目的就是执行insert。这个代码实际执行insert的次数至多是4N次(枚举所有元素在与不在的情况),因此可以认为复杂度是O(4N)。

修订:

这个代码实际执行insert次数至多是2N-1次,因此,时间复杂度为O(2N)。

 

63.   第222页,代码3-1,第1行

原文:char src[5] = “AABBCD”;

      char des[5] = “CDAA”;

修订:char src[] = “AABBCD”;

      char des[] = “CDAA”;

 

64.   第232页,代码3-6

原文:

int t1 = CalculateStringDistance(strA, pABegin + 1, pAEnd, strB, pBBegin + 2, pBEnd);

int t2 = CalculateStringDistance(strA, pABegin + 2, pAEnd, strB, pBBegin + 1, pBEnd);

int t3 = CalculateStringDistance(strA, pABegin + 2, pAEnd, strB, pBBegin + 2, pBEnd);

修订:

int t1 = CalculateStringDistance(strA, pABegin, pAEnd, strB, pBBegin + 1, pBEnd);

int t1 = CalculateStringDistance(strA, pABegin + 1, pAEnd, strB, pBBegin, pBEnd);

int t1 = CalculateStringDistance(strA, pABegin + 1, pAEnd, strB, pBBegin + 1, pBEnd);

 

 

65.   第237页的倒数第2行:

原文:欢迎光临微软亚洲研究院首页

应为:微软亚洲研究院成立于1998年,我们的使命

 

66.   第242页,第17行

原文:O( max(Length(h1) + Length(h2) ))

修订:O( Length(h1) + Length(h2) )

 

67.   第247页,第2行

原文:Else

修订:else

 

68.   第247页,第17行

原文:; //已经没有元素了,所以不能pop

修订:ThrowException();//已经没有元素了,所以不能pop

 

69.   代码3-10中

                   第5行, If应为if

                   第20行,If应为if

                   第22行, While应为while

 

70.   第268页,倒数第12行

原文:我叫他写一个完整的二分排序。

修订:我叫他写一个完整的二分查找程序。

 

71.   第283页,倒数第5行

原文:第一个符号一定是左括号,

修订:第0个符号一定是左括号,

 

72.   第283页,倒数第4行

原文:第一个左括号跟第k个符号匹配。那么从第2个符号到

修订:第0个左括号跟第k个符号匹配。那么从第1个符号到

 

73.   第283页,倒数第3行

原文:到第2n个符号也都是

修订:到第2n-1个符号也都是

 

74.   第284页,第1行

原文;若第一个左括号与第k=2i+1(i=0,1,…,n-1)个右括号

修订:若第0个括号(左括号)与第k=2i+1(i=0,1,…,n-1)个括号(右括号)

 

75.   第290页,第4行

原文:如果叉积为0,则p3在射线p1p2

修订:如果叉积为0,则p3在射线p1p2所在直线上

 

76.   第291页,倒数第2行

原文:如果这些文件被访问的概率相等,那么请问怎样安排它们在磁带上的存储顺序最好?

修订:请问怎样安排它们在磁带上的存储顺序最好?

 

77.   第301页,代码4-3, 第13行

原文:Max = Min = 0;

修订:Max = 0; Min = TotalTime;

 

78.   第301页,代码4-3,第33行

原文:if(Min<currentMin)

修订:if(Min>currentMin)

 

79.   第303页,倒数第1行

原文:应该如何写测试用例呢?

修订:应该如何写测试用例来完成功能测试呢?

 

80.   第304页,第5行

原文:为8位bit,

修订:为8个bit

 

81.   第313页,倒数第4行

原文:2K > 6.7*

修订:2K >= 6.7*

 

82.   创作后记

原文:(关于李东的介绍中)重庆大学软件学院研究生

修订:重庆大学计算机学院研究生

阅读更多
个人分类: 算法
上一篇cvNorm cvNormalize()使用
下一篇《编程之美》读书笔记——“求二进制数中1的个数”(转自http://blog.csdn.net/justpub/article/details/2292823)
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭