Ладно, сперва
if((q<(int)b.size())?a[p]<b[q]:true && p<(int)a.size()){
Yikes.
Это действительно запутанная логика c. У вас есть тройка внутри if, у вас есть true && ...
(что то же самое, что и ...
), и нигде нет абсолютно никакого промежутка, что делает все это еще более нечитаемым. Это не прошло бы ни одного обзора кода, который произошел в пределах 100 футов от меня. Еще до того, как я заглянул слишком далеко в ваш код, я догадался, что именно в этом проблема.
Итак, в вашем примере, когда вы попытаетесь объединить один раз в последний раз, вы получите следующие значения:
a = {35, 54, 67}
b = {3, 4, 23, 89}
Давайте пройдем через это с вашим слиянием ... Все хорошо для первых нескольких циклов, пока у вас не будет:
p = 3
q = 3
x = 7
i = 6
v = {3, 4, 23, 35, 54, 67, 0}
Теперь мы идем в l oop, i < x
верно, поэтому мы все еще идем. И мы доберемся до вашего интереса, если
q < b.size()
верно, 3 < 4
. Итак, мы смотрим на a[p] < b[q]
или a[3] < b[3]
. Ой! Ты видишь проблему? a[3]
вне диапазона. Это означает неопределенное поведение.
Вместо того, чтобы пытаться сделать все это в одном l oop, я бы попытался написать чистый код вместо короткого кода и использовать другой l oop. Этот l oop будет очищаться в зависимости от того, какой a
или b
вы оставили после того, как очистили другой (или, как я написал, это будут два цикла, из которых будет запущен только один) .
Это будет выглядеть так:
size_t p = 0, q = 0, i = 0;
while(p < a.size() && q < b.size()) {
if(a[p] < b[q]) {
v[i++] = a[p++];
} else {
v[i++] = b[q++];
}
}
while(p < a.size()) {
v[i++] = a[p++];
}
while(q < b.size()) {
v[i++] = b[q++];
}
Вы заметите пару вещей, которые я здесь изменил:
- Я переехал из * От 1036 * до
size_t
, поэтому вы можете избежать всех этих уродливых приведений повсюду, поскольку ваши переменные уже будут соответствовать типу размеров вектора. - Я разделил два цикла, чтобы освободить, какой бы из двух векторов еще не было имеет значения.
- Я перешел на
while
, так как я думаю, что они выглядят здесь лучше.