在归并排序中定义数组 T aux[r-l+1]; 编译报错“应输入常量表达式”,在声明数组大小的时候不是不能引用形参,为什么老师在演示的时候可以正常运行呢?

来源:

城续缘

2016-11-02

http://szimg.mukewang.com/5819d7ce00016ae808700792.jpg

写回答

5回答

liuyubobobo

2016-11-02

C++的标准是一直在升级的,同时,相应的编译器也是不断升级的。而且,不同的编译器实现,会稍微有些区别。这有点儿像对于同样的Web标准,不同的浏览器有不同的实现,所以同样的代码在不同的浏览器中就会产生一定的差异。可以看出你使用的是VS。微软的VS对C++标准的实现有些地方有些不同。这里便是其一。C++99的标准已经允许了数组声明中数组的长度可以使用变量 variable-length arrays (VLAs),但是微软的VS实现中不允许。正是因为类似这样的差异,在很多在线的编程系统中,会将Visual Studio C++编译器单独列出来;或者如果服务器不支持Windows,干脆就不支持Visual Studio C++的编译器。


不过这样一个细节的语法问题很容易绕过去。下面列出了几种可能的解决方案:

1 最简单的方法是使用vector代替数组。vector<T> aux(r-l+1);

2 使用vector可能开销比较大,可以在merge子过程中,用new方法创建aux数组,不过不要忘记了在最后delete掉哦。

3 其实整个归并排序中,排序n个数据的话,相应的只需要一个aux[n]的额外空间辅助归并过程。可以将aux数组的开辟放在mergeSort中,之后将aux这个数组作为参数传给merge子过程。这样做的话,merge中处理arr和aux两个数组的索引偏移问题也解决了:)


值得一提的是:归并排序有一个很偏门的优化,就是在用aux传参上做文章。我实测优化效果并不好,但是思路挺有意思。有时间写一篇文章给大家参考:)


11
1
宝慕林3490596
刘老师,我的是VS2015,所以会出现这个问题,用您说的这三种方法都试了下,都能很好解决这个问题 同时也有些疑问 1、用vector会导致排序很慢,就用了您说的第二种new的方法,最后需要delete调aux数组,是指在 __merge 函数体内的末端delete吗?(我试了能排序,但是不知道是不是有问题) 2、第三个方法不太明白,也是用new的方法开辟吗?后面偏移问题要怎么改呢
2017-03-03
共1条回复

城续缘

提问者

2016-11-03

谢谢老师的回答,讲得很清楚,通过数组new的方法已经解决问题了!

2
0

iChrisJ

2017-10-10

T* aux = new T[r - l + 1];


0
0

ALGO_cui

2017-03-31

老师,

#include<vector>

vector<T> aux(r-l+1);

还是报错。

0
1
liuyubobobo
请尝试使用new的方式开辟空间:)
2017-10-11
共1条回复

ALGO_cui

2017-03-31

抱歉,网络出问题,多发了一次

0
0

算法与数据结构(C++版) 面试/评级的算法复习技能包

课程专为:短时间内应对面试、升职测评等艰巨任务打造

11187 学习 · 1614 问题

查看课程