TAOCP-Reading-计算机程序设计艺术阅读-1-2

这篇博客介绍了《计算机程序设计艺术》中的算法表示规则,强调了步骤顺序的重要性,例如在E3算法中的细节。博主通过举例说明如何理解和执行算法,建议读者准备纸笔,通过实例跟进行动。还提到了数组下标表示法以及算法执行的正确方式,包括尾递归的一个例子,并以Intel_X86_汇编展示了Euclid函数。
摘要由CSDN通过智能技术生成

昨天翻译到n++,今天继续

上一篇:https://blog.csdn.net/qq_43057060/article/details/95316231

正文

注意E3中的步骤顺序是很重要的,“m <- n,n <- r"和"n <- r,m <- n"是完全不一样的.因为后者意味着n的初始值将会在把它赋值给m前被覆盖掉.因此上面的代码序列等同于"n <- r,m <- r"当多个变量被设为相同的值时,我们可以用连箭头。例如"n <- r,m <- r"可以被写成“n <- m <- r”。交换两个变量的值,可以写成"交换m <> n"他可以用一个辅助的数字t并写作"Set t <- m,m <- n,n <- t”
一个算法从它编号最小的步骤开始,通常为第一步,除非特殊情况,否则按顺序执行后续步骤。在E3中“跳转到E1”表示一个明显的执行顺序。步骤E2中的动作开始于一个条件"如果r=0"也就是说,如果r!=0,就什么也不会发生.我们或许已经加上了一句无用的句子——“如果r!=0,跳到第三步”
一个粗竖线(饶恕作者没加)出现在E3后表示算法结束,恢复文字.
我们现在已经解释了几乎所有的用于标记算法的规则,除了用于标记"下标"或"引索化"的数组的元素的规则.假设我们有n个数据u1,u2······un;我们用u[j]替代uj表示其中的第j个元素,此表示u[j]经常被使用,相似的,a[i,j]有时被用来表示一个双重下标,就像aij.有时多个字母被用作变量名,通常大写;因此TEMP应当用作一个临时保存结果值的变量,PRIME[K]应当是第K个质数,and so on~~~

​ 对算法的表现形式说太多了,现在我们来执行一下,他因该立即被提及,以免读者期望阅读一个算法就像在读小说。

我们老师就经常对我们说,“以为侬来读小锁死呢”(上海话:以为你在读小说书那),我一开始也真在把他当小说书读

这样的尝试将会使它变得非常的难理解什么发生了。一个算法必须被认为是可信的,并且最好的学习一个算法到底是什么的方法是执行他。阅读者应当时刻准备着一支笔和一张纸,在遇到每一个算法时,通过一个例子了解它到底是什么。通常,一个示例的大纲将会被给出,或读者可以轻松举一个。下面我们给出了一个例子,这是一种轻松且简单的方式去理解一个给定的算法,并且其他所有方法通常是失败的。

于是高德纳举了个例子——m=119,n=544,下面是示例C++
#include<iostream>
using namespace std;
int euclid(int m,int n);
int main(){
    int m,n;
    cout<<"m=";
    cin>>m;
    cout>>"n="
    cin<<n;
    m=euclid(m,n);
	cout<<"r=0\n结果是:"<<m<<endl;
	return 0;
}
int euclid(int m,int n){
	int r;
	while(true){
		//E1
		r=m%n;
		cout<<"r=m%n="<<m<<'%'<<n<<'='<<r<<endl;
		//E2
		if(r)cout<<"r!=0"<<endl;
		else return n;
		//E3
		m=n;
		cout<<"m="<<m<<endl;
		n=r;
		cout<<"n="<<n<<endl;
        cout<<endl<<endl;//two spare line for clear seen
	}
}

尾递归写法:

#include<iostream>
using namespace std;
int euclid(int m,int n);
int main(){
    int m,n;
    cout<<"m=";
    cin>>m;
    cout<<"n=";
    cin>>n;
    m=euclid(m,n);
	cout<<"r=0\n结果是:"<<m<<endl;
	return 0;
}
int euclid(int m,int n){
	//E1
		int r=m%n;
		cout<<"r=m%n="<<m<<'%'<<n<<'='<<r<<endl;
	//E2
		if(r)cout<<"r!=0"<<endl;
		else return n;
	//E3
		cout<<"m="<<n<<endl;
		cout<<"n="<<r<<endl;
		cout<<endl<<endl;//two spare line for clear seen
		return euclid(n,r);
}
//该写法会被优化成第一种写法

Intel_X86_汇编_(仅包括euclid函数,无LOG)

.E1
movl %edi %eax
idivl %esi
cmp %edx 0
.E2
jnz .E3
movl %esi %eax
ret
.E3
mov %esi %edi
mov %edx %esi
jmp .E1

执行结果:

m=119
n=544
r=m%n=119%544=119
r!=0
m=544
n=119


r=m%n=544%119=68
r!=0
m=119
n=68


r=m%n=119%68=51
r!=0
m=68
n=51


r=m%n=68%51=17
r!=0
m=51
n=17


r=m%n=51%17=0
r=0
结果是:17

完美的CODE自夸遭雷劈。


Thanks For Reading


下一篇:https://blog.csdn.net/qq_43057060/article/details/95898885

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值