作业帮 > 体裁作文 > 教育资讯

如何改写程序

来源:学生作业帮助网 编辑:作业帮 时间:2024/11/02 07:31:28 体裁作文
如何改写程序体裁作文

篇一:程序分析及改写程序

1、如下是一个4-2编码器的vhdl描述,其真值表如图所示。试用case语句代

LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY encoder IS

PORT(A:IN STD_LOGIC_VECTOR(3 DOWNTO 0);

Y: OUT STD_LOGIC_VECTOR(1 DOWNTO 0));

END encider;

BEGIN With A select y<= “00” WHEN "0001", “01” WHEN "0010",

“10” WHEN "0100",

“11” WHEN "1000", “ZZ” WHEN OTHERS; END aa;

2、如下是一个优先编码器的vhdl描述,,其真值表如图所示。其中P(0)优先级最高,P(3)优先级最低。试用一条合适的并发描述语句完成该功能描述。 library ieee; use ieee.std_logic_1164.all; entity encoder is port(p:in std_logic_vector(0 to 3);y:out std_logic_vector ( 0 to 1) ); end encoder; architecture rtl of encoder is

beginelsif (P(3)=’1’) then y<=”11”; process(P)else y<=”ZZ”;

beginend if;

if (P(0)=’1’) then y<=”00”;end process;

elsif (P(1)=’1’) then y<=”01”; end rtl;

elsif (P(2)=’1’) then y<=”10”;

3、分析所给VHDL描述程序,说出其实现的功能;根据输入端口信号激励波形,画出仿真输出波形。

LIBRARY ieee;

use ieee.std_logic_1164.all; LIBRARY ieee;

entity dff1 is use ieee.std_logic_1164.all; port(d,clk: in std_logic; entity shift is

q: out std_logic);port(a,clk: in std_logic; end dff1;b: out std_logic); architecture dff1_behave of dff1

is end shift;

begin architecture struct of shift isprocess(clk) Component dff1

begin Port(d,clk:in std_logic; if (clk'event and clk='1') then q: out std_logic); q<=d; End component;

end if; Signal z:std_logic_vector(0 to 2);end process; begin

end dff1_behave; D1:dff1 port map(a,clk,z(0));D2:dff1 port map(z(0),clk,z(1));D3:dff1 port map(z(1),clk,z(2));D4:dff1 port map(z(2),clk,b);

end struct;

篇二:怎样写好程序

1、写每个程序都是为了解决某个问题,你应该去思考我该怎样去解决这问题,而不是急于 的去考虑我程序到底怎么写、怎么去实现,往往有些同学他动手最快,写得很积极,但他不 一定是写的最好的,也不一定是最快写出程序的人。所以当你遇到问题的时候,你需要不断 的去思考,去想我怎样去解决这问题,JAVA语言体现的是一种思想,这种思想得经过很长 时间去磨炼、去体会的,不是一天两天就能理解的。

2、比如最简单的例子:1+1等于多少?这个程序那么你就应该去思考我在现实生活中怎样去做这个题?那么这个题很简单,在纸上直接写上2就OK了。那么在程序中要怎样去写呢? 这个题用程序写的话太简单了,你会马上有思路了,知道该怎样去实现。如下: 实现一:

public static void main(String[] args){

System.out.println(1+1);

}

实现二:

public static void main(String[] args){

int a = Intger.parseInt(args[0]) ;//参数String类型转换成int类型

int b = Intger.parseInt(args[1]) ;

System.out.println(a+b);

}

第一个程序实现了我们想要的功能,能算出1+1=2,这已经达到了我们的目标。但是这个程序有他的缺点,这个程序只能算1+1,那么我想算1+2呢?很显然只能在加一行System.out.println(1+2);,那么这样的话就改变了程序的结构。程序没有任何的扩展性,说白了这个程序没有任何的价值。可是优点是简单,最简单的实现了功能。

第二个程序同样实现了功能,但相对于第一个程序,第二个程序显得更加的强大,不紧紧能算出1+1,能算出任何两个数的相加。那么这个程序就很灵活,具有可扩展性。缺点是稍显复杂。

总结:其实对于初学者来说只要能实现第一种方式就可以了,不管什么问题只要能解决就OK。那么怎样能一下就想到第二种方式呢,这个得需要时间去积累,不断的去审视代码,要深入理解和体会面向对象的思想。

3、写一个程序打印以下这些数。

1 10 100 1000

2 20 200 2000

3 30 300 3000

4 40 400 4000

5 50 500 5000

这个程序要比1+1的题要复杂的多,但是当你实在是想不出怎样去写,没有一点思路的时候,那该怎么办呢?我建议可以这样,先可以不要想着我一下就实现了功能,我能不能先把第一行打印出来呢?如果第一行都不会怎打印出来,我建议就可以看看老师写好的程序或者同学的程序是怎么实现的,如果你自已知道怎么打印第一行如下:

实现一:

public static void main(String[] args){

System.out.println(1+””+10+””+100+””+1000);

}

OK这样最简单的打印出来了,那么是否可行呢,很明显肯定不能这样写。因为你偏离了题的意思,如果这样打印出来,还不如全打印出来呢,打印出5行数据。这样肯定不行,写跑

题了。

实现二:

public static void main(String[] args){

for(int i=1;i<5;i++){

System.out.print(i);

}

//打印出1 2 3 4

}

思考:这虽然打印出一行数据了,但不是我想要的结果,这个时候就得需要思考了。去找规律了,发现除了第一个数每个数是前一个数的10倍,那好了我每次打印的时候去乘以10。 实现三(改进):

public static void main(String[] args){

for(int i=1;i<5;i++){

System.out.print(i*10);

}

//打印出10 20 30 40

}

思考:这个结果还不是我想要的,是乘以10了,但是结果是我循环i的值,每个数的10,而不是前面的数的10倍,也就是说我想要的是第一行,都是以1为单位的10倍数,如:1*10,10*10,100*10,而不是20或者30什么的。但是怎么解决这问题,因为i的值是不断变化的,不可能总是1。那么如果我不用i的值(这个for循环我只是用来控制输出几例数据),我可以定义一个变量来等于1。

实现四(改进):

public static void main(String[] args){

int num=1;

for(int i=1;i<5;i++){

num=num*10;//因为当前的值是前面的值的10倍,所以要把前面计算出的值存起来。

System.out.print(num);

}

//打印出10 100 1000 10000

}

思考:越来越接进想要的结果了,但是这个结果还是不行,因为是从10开始打印的,而不是从1开始,那么也就是说,当i=1的时候说明是要打印第一例的数,发现一个规律第一例的数是不需要乘以10的,所以要判断一下。

实现四(改进):

public static void main(String[] args){

int num=1;

for(int i=1;i<5;i++){

if(i == 1){

System.out.print(num);

}else{

num=num*10;

System.out.print(num);

}

}

//打印出110 100 1000

}

思考:终于第一目标实现了,打印出我想要的第一行数据,但是整个题的目标是打印5行而不是1行,那么还得去找规律,第一行数据是以1(num =1)为单位的,依此类推第二行就是以2为单位为的,也就是当num的值等于2的时候就会出现第二行的数据,那这个数是总是变化的并且是累加的,所以外面在套个循环就可以解决这问题。

实现五:

public static void main(String[] args){

for(int j=1;j<6;j++){

int num=j;

for(int i=1;i<5;i++){

if(i == 1){

System.out.print(num+”

}else{

num=num*10;

System.out.print(num++”

}

}

System.out.println();

}

/*打印出

1 10 100 1000

2 20 200 2000

3 30 300 3000

4 40 400 4000

5 50 500 5000*/

} ”); ”));

篇三:教你如何写快速的程序

第1讲——如何写快速的程序

1. 善于使用符号常量定义(宏定义)

原则1:对于运行过程中值不变的数据,尽量在常量说明中赋值,编译时分配存储空间并立即赋值(替换),这样既增加不了多少编译时间,又节省了目标代码的执行时间,同时增强程序的通用性和可读性。如:

const int PI = 3.14;

原则2:对于很短又频繁调用的函数,使用宏函数(或内联函数),因为在函数调用时,系统需要开辟工作栈并保存当前的工作环境,因此需要耗费时间;而宏函数是在编译阶段嵌到代码中,相对于函数来说,使用宏函数的程序执行速度更快。但编译器对宏只简单地进行文本替换,使用时要避免出错。以下的宏函数完成取较小值的操作。

#define MAX(x, y) (x >= y ? x, y)

2. 优化算术运算

原则1:各种算术运算的执行效率差别很大,稍加注意即可提高效率。表1给出了各种算术运算的效率比较。

乘和除的运算速度要比加和减慢很多,应该用加和减来优化乘和除,如:

3 * x ?x + x + x

使用自增、自减或符合运算符,如:

a = a + 1; ? a++;

sum = sum + a[i];? sum += a[i];

原则2:乘除和对2n求余。大部分C编译器的求余运算时调用子程序完成的,比较费时。如果求2n的余数,可以通过位操作完成。如果乘或除2n,可以通过移位操作完成。如:a % 2 ?a & 1

a / 2 ?a >> 1

a * 2 ?a << 1

原则3:避免重复计算。相同的运算最好执行一次并暂存起来,这样虽然增加了一个临时变量,但实际编译时,系统也会为运算的中间结果设置中间存储单元,因此,这样做不会增加内存消耗。如:

temp = a /(b * c); x = x + a /(b * c); ? x = x + temp; y = y + a /(b * c);y =y + temp;

再有如下语句,编译程序为这两条语句分别安排单元,分配操作指令,但实质上两个表达式的绝对值相同,可以改为:

x = a – b; x = a – b; ? y = b – a; y = -x;

原则4:有利于编译优化。编译程序的处理过程是对源程序自上而下逐句扫描,以基本块为单位进行的,所谓基本块指的是说明语句、复合语句、条件语句、循环语句等,编译优化一般是在基本块内进行。

3. 优化逻辑运算

大多数编译程序在计算逻辑表达式的值时都具有短路功能,所谓短路功能指的是自左向右计算,一旦可以得到表达式的结果就跳出表达式的计算。如:

(i >=0 && a[i] !=x)

先计算i >=0的值,若为真,再计算下一个表达式,若为假,则整个表达式的值为假,余下的表达式就不进行计算了,

同理,对于:

(i >=0 || a[i] !=x)

先计算i >=0的值,若为假,再计算下一个表达式,若为真,则整个表达式的值为真,余下的就不再做了。

需要注意的是,如果余下的表达式中要改变变量的值,则可能会出错,如:

(x > y && x++ < z)

4. 合理安排条件语句的顺序

原则1:将执行概率较大的条件放在前面,如:

if (x == 0 ) sign = 0; if (x > 0 ) sign = 1;

else if (x > 0) sign = 1;

?else if (x < 0) sign = -1;

else sign = -1; else sign = 0;

原则2:避免重复判断,如:

if (x >= 0)

if (x > 0)

else

5. 改善循环结构

原则1:由于循环语句有赋初值、条件判断、改变循环变量等时空开销,所以能用表达式实现的功能就不用循环语句,例如执行几次的循环:

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

? sum += a[0] + a[1] + a[2];sum +=a[i];

原则2:合理安排嵌套循环,在不影响程序逻辑的情况下,将循环次数多的作为内循环(即小循环套大循环),例如下面的程序:

for (i = 1; i <= 10; i++)---------执行11次 共执行11+1010+1000for (j = 1; j <=100; j++) --------10*101次 =2021次 x++; ---------执行10*100次

for (j = 1; j <=100; j++)--------执行101次 共执行101+1100+1000for (i = 1; i <=10; i++) --------执行100*11次 =2201次 x++; --------执行1000次

原则3:合并循环,避免冗余循环,在循环体执行一次完成尽可能多的事。如:

for (max = a[0], i = 1; i

if (max < a[i]) max = a[i];for (i = 1; i < n; i++)

for (min = a[0], i = 1; i

if (max < a[i]) max = a[i];if (min > a[i]) min = a[i];

if (min > a[i]) min = a[i];

}

原则4:循环不变式外提,将与循环变量无关的操作提到循环外面,这个优化可以大大提高代码的效率,如: temp = x * y; for (i = 1; i < 100; i++) for (i = 1; i < 100; i++) ?sum = x * y + a[i];sum = temp + a[i];

原则5:循环无开关,循环体中如果出现与循环变量无关的判断,则可以在循环外面进行判断,例如程序段,虽然修改后的程序段中有两个循环,但实际上只执行了1个,而且还少了99次判断:

foe (i = 0; i < 100; i++) if (x > 5)if (x > 5) for (i = 0; i < 100; i++) x[i] = a[i] + b[i]; ?x[i] = a[i] + b[i];else else x[i] = a[i] – b[i]; for (i = 0; i < 100; i++) x[i] = a[i] - b[i];

原则6:对数组元素的访问需要进行变址运算,例如,有变量定义int a[10],程序中需要将a[i]转换成a + i * (sizeof (int)),因此,如果元素个数较少,应避免使用数组,而且尽量把对数组元素的访问操作提到循环外面。

6. 几个实例

例1:打印所有小于1000的素数。

【程序1】基本程序。

int Prime(int x)

{

for (int i = 2; i < n/2; i++)

if (x % i == 0) return 0;

return 1;

}

int main( )

{

for (int i = 2; i <= 1000; i++)

if (Prime(i) == 1) printf("%5d", i);

return 0;

}

【程序2】使用符号常量,利用sqrt函数缩小循环执行的次数。

#define n 1000

int Prime(int x)

{

for (int i = 2; i < sqrt(x); i++)

if (x % i == 0) return 0;

return 1;

}

int main( )

{

fo(来自:WwW.ZW2.CN 爱作文 网)r (int i = 2; i <= n; i++)

if (Prime(i) == 1) printf("%5d", i);

return 0;

}

【程序3】将循环不变式sqrt(x)提到循环外面。

#define n 1000

int Prime(int x)

{

m = sqrt(x);

for (int i = 2; i < m; i++)

if (x % i == 0) return 0;

return 1;

}

int main( )

{

for (int i = 2; i <= n; i++)

if (Prime(i) == 1) printf("%5d", i);

return 0;

}

【程序4】用乘法代替开平方运算,实验表明可大大提高程序的执行速度。

#define n 1000

int Prime(int x)

{

for (int i = 2; i * i < x; i++)

if (x % i == 0) return 0;

return 1;

}

int main( )

{

for (int i = 2; i <= n; i++)

if (Prime(i) == 1) printf("%5d", i);

return 0;

}

【程序5】根据数论原理对能被2、3、5整除的特殊校验,被2整除的性质使大约一半的数不用执行for循环,被3整除的性质使余下1/3的数不用执行for循环,被5整除的性质使余下1/5的数不用执行for循环,对于for循环只考虑能否被奇数整除即可,从而大大减少循环次数。

#define n 1000

int Prime(int x)

{

if (x % 2 == 0) return (x == 2);

if (x % 3 == 0) return (x == 3);

if (x % 5 == 0) return (x == 5);

for (int i = 7; i * i < x; i = i + 2)

if (x % i == 0) return 0;

return 1;

}

int main( )

{

for (int i = 2; i <= n; i++)

if (Prime(i) == 1) printf("%5d", i);

return 0;

}

例2:将一维整型数组A调整为左右两部分,左边所有元素均为奇数,右边所有元素均为偶数。

【程序1】同学写的程序,完全正确,逻辑也很好,但代码效率有待提高(重复比较)。 void Sort(int x[ ], int n)

{

int i , j;

for ( i = 0, j = n - 1; i < j; )

if (x[i] % 2 == 0 && x[j] % 2 != 0)

{

int temp = x[i]; x[i] = x[j]; x[j] = temp;

i++; j--;

}

else if (x[i] % 2 != 0)

i++;

else j--;

}

【程序2】改进后的程序逻辑更清晰,且代码效率高。

void Sort(int x[ ], int n)

{

int i= 0, j = n - 1;

while (i < j)

{

while (x[i] % 2 != 0) i++;

while (x[j] % 2 == 0) j--;

if (i < j) {

int temp = x[i]; x[i] = x[j]; x[j] = temp;

i++; j--;

}

}

}

体裁作文