转几道C#题及答案
1.string str=null和string str=""有什么不同?
2.remoting和webservices有什么不同?
3.遍历所有的<filename>,使用递归方法,画出流程图。
答案:
1. 第一个是空引用(托管堆里无对象),第二个托管堆里有个空字符串
2. 都能开发分布式多层应用程序设计,如果需要在不同系统之间进行互操作,应该选择使用开放标准 (SOAP、XML、HTTP) 的 Web 服务方法,;如果各种系统中的所有组件都是 CLR 托管的,则 .NET Remoting“可能”是正确的选择
其他:
WebService是工业标准,基于Http协议传递.
Remoting是.Net一个RPC调用机制,可以基于TCP协议,性能相对好
NET Remoting主要用于分布式程序开发,小项目一般用不到,且更适合企业内部网(局域网使用),而且支持二进制传输与比WebServices速度要快。WebService实际是个比较花消的东西,中看不中用,在数据量大的时候,速度奇慢无比。所以一般也很少用。
http://www.microsoft.com/china/MSDN/library/archives/library/dndotnet/html/dotnetremotearch.asp#dotnetremotearch_topic4
3.
using System;
using System.IO;
class ListAllFilesDemo
{
public static void Main ()
{
Console.Write("请输入要查询的目录: ");
string dir = Console.ReadLine();
try
{
ListFiles(new DirectoryInfo(dir));
}
catch(IOException e)
{
Console.WriteLine(e.Message);
}
}
public static void ListFiles(FileSystemInfo info)
{
if(!info.Exists) return;
DirectoryInfo dir = info as DirectoryInfo;
//不是目录
if(dir == null) return;
FileSystemInfo [] files = dir.GetFileSystemInfos();
for(int i = 0; i < files.Length; i++)
{
FileInfo file = files[i] as FileInfo;
//是文件
if(file != null)
Console.WriteLine(file.FullName + "/t" + file.Length);
//对于子目录,进行递归调用
else
ListFiles(files[i]);
}
}
}
以下是我自己的一点体会:
1. string str=null,只是在栈中存在一个str 引用。
2. 递归算法:
一般在递归函数末尾设置两个选择(if …..else ).
1) 调用自身,向下一级延伸。(并不是真正的出口)
2) 递归的终止(真正的出口)
附:
递归算法及其应用
http://www.mydrs.org 2002-7-4 大榕树
[递归的描述]
由上面的例子可以看出,一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。因此,在考虑使用递归算法编写程序时,应满足两点:1)该问题能够被递归形式描述;2)存在递归结束的边界条件。
递归的能力在于用有限的语句来定义对象的无限集合。用递归思想写出的程序往往十分简洁易懂。
[例2] 给出一棵二叉树的中序与后序排列。求出它的先序排列。
[分析] 通过对比二叉树的中序与后序排列,我们可以找出根节点及左右子树。同样的,有可以通过对比左子树的中序与后序排列,找出左子树的根节点……可见,该问题能够被递归描述。当找到最后一个根节点时,递归无法再进行下去,这就是递归结束的边界条件。由此可见,递归算法中常常隐含了分治思想。程序如下:
program chu01_3;
var z,h: string;
procedure find(a,b:string);
var
s,l : integer;
begin
l:=length(b);
if l=1 then Write(b) {边界条件及递归返回段}
else
begin {递归前进段}
Write(b[l]);
s:=pos(b[l],a);
if s-1>0 then find(copy(a,1,s-1),copy(b,1,s-1)); {递归左子树}
if l-s>0 then find(copy(a,s+1,l-s),copy(b,s,l-s)); {递归右子树}
end;
end;
begin
Readln(z);
Readln(h);
Find(z,h);
Readln;
end.
[递归的应用]
1.经典递归
例如hanoi塔问题:经典的递归,原问题包含子问题。有些问题或者数据结构本来就是递归描述的,用递归做很自然。
2.递归与递推
利用递归的思想建立递推关系,如由兔子生崽而来的fibonacci数列。但递推由于没有返回段,因此更为简单,有时可以直接用循环实现。
3.分治
不少分治方法是源于递归思想,或是递归分解+合并处理。
4.回溯
规模较小的问题用回溯解决比较自然。注意递归前后要保证现场的保存和恢复,即正确的转化问题。
5.动态规划
动态规划的子问题重叠性质与递归有某种相似之处。递归+动态修改查表是一种不错的建立动态规划模型的方法。
6.其他
其他么,就是不好归类。例如表达式处理,排列组合等。附带说一下,用递归来处理打印方案的问题还是很方便的。
[例3] 求把一个整数n无序划分成k份互不相同的正整数之和的方法总数。
[分析] 这是一道动态规划题,动态方程如下:
f[i-1,j]+f[i,j-i]+1 ((j mod i=0) and (j div i=1))
f[i,j]:= f[i-1,j] (i>=j)
f[i-1,j]+f[i,j-i] (else)
s:=f(k,n-k)
本题可以用循环来实现递推,也可以考虑用递归求解。主过程如下:
方案一:
Procedure work(I,j:longint; var s:longint);
Var t:longint;
Begin
If (i=1) or (j=1) then s:=1
Else if (i=0) or (j=0) then s:=0
Else begin
if (j mod i=0) and (j div i=1) then
begin
work(i-1,j,s);
t:=s;
work(i,j-1,s);
s:=s+t+1;
end
else if (i>=j) then
work(i-1,j)
else begin
work(i-1,j,s);
t:=s;
work(I,j-1,s);
s:=s+t;
end;
End;
方案二:procedure search(v,w,last:byte);
var i:byte;
begin
if w=0 then inc(count)
else
if w=1 then
if v>=last then search(0,0,0) else
else for i:=last to v-1 do search(v-i,w-1,i);
end;
可以看出,方案一的程序较为冗长,消耗栈空间较大;而方案二较为简洁明了,所用的栈空间也较小,效率较高。因此,使用递归算法也有一个优化问题。算法的简洁与否直接制约了程序的可行性和效率。
[总结]
递归使一些复杂的问题处理起来简单明了,尤其在学习算法设计、数据结构时更能体会到这一点。但是,递归在每一次执行时都要为局部变量、返回地址分配栈空间,这就降低了运行效率,也限制了递归的深度。因此,在必要的时候可以只使用递归的思想来求解,而程序则转用非递归的方式书写。