详细分析.net 反序题目



Reverse办法的感化是将array数组中,从begin下标到end下标之间的元素反序一下,如一个数组初始值是[1, 2, 3, 4, 5, 6],begin为1,end为4,那末当调用了Reverse以后,array数组中的元素便挨次成为[1, 5, 4, 3, 2, 6],此中从array[1]到array[4]以前的元素被反序了。别的弥补一点……实正在本没有用弥补:这个办法必要对于传入参数的精确性举行校验,假如用户调用该办法时传入了不法的参数,那末则必要抛出非常,并写清起因。您可使用您喜爱的说话来完成:C#,VB,Java,Ruby,Python……可是请没有要应用内置库中曾经有的功效。:)

  很复杂,没有是吗?只惋惜停止到今朝,也惟独1人给出了精确谜底。假如您没有做过这道标题,那末正在检查上面的阐发以前,没有妨拿张纸拿支笔,写下您的谜底,而后再听老赵缓缓讲来…

主体逻辑
  这道标题的主题逻辑实正在很是复杂。没有便是把数组中的一部份反序吗?没有过从这一点下面来讲,代码的清楚水平也有较年夜差异。好的做法以及平凡的做法,从编程难度以及懂得上都有必定差异。比方:

一、很多伴侣的做法是:既然是反转数组的一部份元素,那末只需找到两头的地位,而后计较出以及begin的偏偏移量,而后……怎样怎样一搞,就实现为了——嗯,仿佛还必要按照举行begin以及end两头的元素个数是奇数仍是偶数别离搞定。

二、另外一些伴侣的做法是:开一个新数组(长度为end - begin + 1),将begin到end之间的元素放到新数组中去,而后反序,而后再复制返来。

三、另有一个伴侣觉得用栈:把begin到end之间的元素给push到栈中,再一个一个pop出去挨次赋值给begin到end,如许就反序了……唔!数据布局学的没有错!

  只惋惜,如许的做法都繁杂了一些。3种做法的工夫繁杂度均为O(end – begin),可是惟独第一种做法的空间繁杂度是O(1),尔后二者也都是线性的空间繁杂度。那末老赵眼里最佳的做法是甚么呢?

 

public static void Reverse(int[] array, int begin, int end)
{
while (end > begin)
{
int temp = array[begin];
array[begin] = array[end];
array[end] = temp;

begin++;
end--;
}
}

end以及begin两个下标从初始值开端挨次向两头迫近,每一次都互换一下数组中的元素。终极,while正在断定的时辰会看见end == begin(begin以及end之间统共奇数个元素),或者end < begin(begin以及end之间统共偶数个元素)。不管哪一种环境,都暗示反序曾经实现。
参数校验
下面的做法应当说是最复杂的一种,没有过理论正在评判谜底的时辰,直接成果精确,老赵都觉得是精确的。只惋惜,多少乎没有伴侣正在“参数校验”这方面尴尬刁难于。

  趁便提一下的是,有位伴侣给我留言很故意思:“教师只给了一个测试数据,假如要用别的测试数据的话比方比拟非凡的,那就教师下次把测试数据列好。”这句话让我木然:测试数据是无量无尽的,莫非必要都列出去?平常写顺序,用户会指出他的全部操纵步调吗?给测试数据的目标是为了帮忙懂得题意,标题的请求都写分明了,做题才故意义。假如一道标题只请求把给出的测试数据运转,那末又有谁没有会做呢?老赵此处便可以当即给出一个全能模板:

if (...)
{
return ...
}
else if (...)
{
return ...
}

...

按理来讲,即便标题中没有写明必要参数校验,一个良好的完成也应当自带这一点。

实正在只需认真一些,把参数全部的差错环境罗列出去其实没有是难事:

那末,其余一些环境能否应当一并断定呢?比方end < 0,array.Length == 0大概begin >= length。老赵觉得“没有断定也没有干系”,由于以上的断定曾经确保没有会呈现额定的差错环境了。那末begin == end能否算是题目呢?老赵觉得,这个断定也能够省略。没有过……假如begin > end,那末能否应当把二者的数值举行互换?我没有晓得为甚么有些伴侣这么做了,没有过老赵觉得,个别来讲一个办法没有应当为参数举行额定“调解”——实正在各年夜类库都没有会如斯多此一举。假如哪位伴侣有没有同观点,咱们能够持续接头。

罕见差错
  正在各类谜底,以及平常口试进程中,这道题总归会有一些很是典范的差错产生。此中给老赵的感到也很是故意思,没有知此中的“思绪”能否如老赵猜想那样。

正在办法及第行输出以及输入
  有没有少伴侣正在代码里安排了如许的代码:

static void Reverse(int[] array, int begin, int end)
{
Console.WriteLine("请输出xxx");
array[0] = Int32.Parse(Console.ReadLine());
...

for (int i = 0; i < array.Length; i++)
{
Console.WriteLine(i);
}
}

为甚么会呈现这类环境?老赵估量是遭到了某些培训机构的影响(察看呈现这个题目的伴侣们的漫衍便知)。这些培训频频夸大输出、输入,而没有让学员有任何“模块”,“类库”,“帮助办法”的定义。学员的不雅念中,任何顺序都要向用户去索要“输出”,而且要“输入”,不然就没有算是顺序。

打印差错,而没有是抛出非常
代码以下:

static void Reverse(int[] array, int begin, int end)
{
if (array == null)
{
Console.WriteLine("数组为空");
return;
}

...
}

除了了以及下面雷同的“思惟”之外,这阐明有些伴侣尚未构成“抛出非常”的不雅念。这象征着正在过往的编程教训中,能够说彻底没有“参数校验”的定义正在脑筋内里。培训机构只是一味地CRUD,展现,写入,却没有“抛出非常”的设法。同理,即便正在标题中曾经明白写清了是“抛出”非常,有些伴侣的写法是如许的:

static void Reverse(int[] array, int begin, int end)
{
try
{
// 互换数据
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}


很明明,他们惟独“捕捉”非常的定义——天然是框架自己抛出的非常——而没有知“抛出”非常。

参考谜底
  如下是老赵给出的参考谜底:

 

static void Reverse(int[] array, int begin, int end)
{
if (array == null)
{
throw new ArgumentNullException("array", "array没有能为空");
}

if (begin < 0)
{
throw new ArgumentOutOfRangeException("begin", "begin没有能小于0");
}

if (end < begin)
{
throw new ArgumentOutOfRangeException("end没有能小于begin", (Exception)null);
}

if (end >= array.Length)
{
throw new ArgumentOutOfRangeException("end", "end超越array最年夜下标");
}

while (end > begin)
{
int temp = array[begin];
array[begin] = array[end];
array[end] = temp;

begin++;
end--;
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值