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, Y4, Y5-1)。
修订:根据题意,不同卷的书组合起来才能享受折扣,至于具体是哪几卷,并没有要求。因为(Y1-1, Y2-1, Y3-1, Y4-1, Y5)能够保证在选择当前折扣情况下,剩下的书种类最多,它比其他组合都好。我们不用再考虑其他可能,如(Y1-1, Y2-1, Y3-1, Y4, Y5-1)。
12. 第34页,倒数第5行
原文:
假设这样的分法存在,那么就可以按照小于10的情况考虑求解。如果要买的书为(Y1, Y2, Y3, Y4, Y5)(其中Y1>=Y2>=Y3>=Y4>=Y5),贪心策略建议我们买Y5本五卷的,Y4-Y5本四卷,Y3-Y4本三卷,Y2-Y3本两卷和Y1-Y2本一卷。由于贪心策略的反例,我们把K本五卷和K本三卷重新组合成2×K本四卷(K = min{Y5, Y3-Y4})。结果就是我们买Y5-K本五卷的,Y4-Y5本四卷,Y3-Y4-K本三卷,Y2-Y3本两卷和Y1-Y2本一卷(K = min{Y5, Y3-Y4})。
修订:
假设这样的分法存在,那么就可以按照小于10的情况考虑求解。如果要买的书为(Y1, Y2, Y3, Y4, Y5)(其中Y1>=Y2>=Y3>=Y4>=Y5),贪心策略建议我们买Y5本五卷的,Y4-Y5本四卷,Y3-Y4本三卷,Y2-Y3本两卷和Y1-Y2本一卷。由于贪心策略的反例,我们把K本五卷和K本三卷重新组合成2×K本四卷(K = min{Y5, Y3-Y4})。结果就是我们买Y5-K本五卷的,Y4-Y5+2K本四卷,Y3-Y4-K本三卷,Y2-Y3本两卷和Y1-Y2本一卷(K = min{Y5, Y3-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(V, n)就是我们要求的值。
修订:因此,Opt(V,0)就是我们要求的值
17. 第41页,倒数第10行
原文:用Opt(V', i)表示从第i, i+1, i+2,…, n-1, n种饮料中,算出总量为V'的方案中满意度之和的最大值。
修订:用Opt(V', i)表示从第i, i+1, i+2,…, n-1种饮料中,算出总量为V'的方案中满意度之和的最大值。
18. 第41页,倒数第8行
原文:Opt (V', i) = max { k* Hi + Opt(V' - Vi * k, i-1)}
修订:Opt (V', i) = max { k* Hi + Opt(V' - Vi * k, i+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行:
原文:所以空间复杂度可以降为O(v)。
修订:所以空间复杂度可以降为O(V)。
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)= n * 10n-1。
修订:f(10n-1) = n * 10n-1
51. 第137页:
原文:容易从上面的式子归纳出:f(10n-1)= n * 10n-1。通过这个递推式,很容易看到,当n = 9时,f(n)的开始值大于n
修订:容易从上面的式子归纳出:f(10n-1)= n * 10n-1。通过这个递推式,很容易看到,当n=1010-1时,f(n)的值大于n
52. 第137至138页,倒数第13行
原文:
首先,当k>=10时,k*10 k-1> 10 k,所以f(n)的增加量大于n的增加量。
其次,f(1010-1)=1010>1010-1。如果存在N,当n = N时,f(N)-N>1010-1成立时,此时不管n增加多少,f(n)的值将始终大于n。
具体来说,设n的增加量为m:当m小于1010-1时,由于f(N)-N>1010-1,因此有f(N + m)> f(N)> N + 1010-1 > N + m,即f(n)的值仍然比n的值大;当m大于等于1010-1时,f(n)的增量始终比n的增量大,即f(N + m)- f(N)>(N+m)- N,也就是f(N + m)> f(N)+ m > N + 1010-1+ m > N +m,即f(n)的值仍然比n的值大。
因此,对于满足f(N)- 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+…,则由上可得,
f(n)=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增加量的归纳结果。
又,
n =a*10k+b*10k-1+…< a*10k+(b+1)*10k-1
如果a* k*10k-1+b*(k-1)*10k-2 >= a*10k+(b+1)*10k-1的话,那么f(n)必然大于n。而要使不等式a* k*10k-1+b*(k-1)*10k-2 >= a*10k+(b+1)*10k-1成立,k需要满足条件:k >= 10 +(b + 10)/(b + 10*a)。显然,当k > 11,或者说n的整数位数大于等于12时,f(n)> 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.b1b2…bm
修订:Y=0.(b1b2…bm)
56. 第153页,第12,13行
原文:f(x, y) = f(x, x – y)
修订:f(x, y) = f(y, x – 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的时候,如何计算A(n)呢?
修订:对于n非常大的情况,如n=260的时候,如何计算A(n)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. 创作后记
原文:(关于李东的介绍中)重庆大学软件学院研究生
修订:重庆大学计算机学院研究生
from http://blog.csdn.net/justpub/article/details/2378778#comments)