2015-07-29 4 views
0

Так, ребята, у меня есть проблема разработки алгоритма, который принимает конечный список действительных чисел, отсортированных в порядке возрастания и вещественное число N, иMatlab вопрос алгоритм

-Если там существует два индекса i и j , такие как 1 <= i <j <= numel(L) и L(i)+L(j)=N, затем алгоритм возвращает пару sumToN = [L(i) L(j)]; в том случае, когда существует множество пар индексов с требуемым свойством, функция возвращает одно из допустимых пар,

-Ели равенства L(i)+L(j)=N не выполняются для любых индексов i и j, такие, что 1 <= i < j <= numel(L), функция весть пустая пара Ret.

L = [1 2 2 3]; 
N = 3; 
sumToN = 0; 

for i=1:numel(L); 
    for j=1:numel(L); 
    if i<j; 
     if L(i) + L(j) == N; 

     sumToN = [L(i) L(j)]; 
    display(sumToN); 
     else 
     Ret = [0 0]; 
     display(Ret); 
     end 
    end 
    end 
end 

Теперь, в этом коде, который я написал в Matlab R2014, независимо от условий, если я получаю странный вывод: окно командной строки отображает два раза вектор sumToN и четыре раза вектор Ret. Любое предложение о том, как решить эту проблему? Я думаю, что алгоритм правильный ...

+0

SO, похоже, не поддерживает разметку LateX, вы можете отредактировать свой вопрос, более читаемый, пожалуйста? благодаря! –

+0

Как я могу это сделать? Мне нужно отображать меньше или равные символы! – james42

+0

old-school '<=' works :) – beaker

ответ

1

Правильный алгоритм и правильность отображения. В вашей петле i<j выполняется 6 раз. То есть для (i, j) пар (1,2), (1,3), (1,4), (2,3), (2,4), (3,4). Поэтому, основываясь на вашем коде, вы должны ожидать отображение 6 раз. В этих парах, основанных на данных в L, условие L(i)+L(j)==3 может быть выполнено дважды (1,2) и (1,3). Таким образом, вы получаете sumToN дважды, а остальные 4 раза Ret отображаются.

Если вы хотите остановить, как только найдете пару, вы должны вернуть значения из этой функции, как только обнаружите L(i)+L(j) == N. Вы должны инициализировать Ret до [0 0] до начала циклов и вернуть это после окончания цикла. Это вернет [0 0], если вы не можете найти L (I) + L (J) == N.

+0

И как я могу остановить цикл, как только будет найдена пара? – james42

+0

Если это функция, вы можете просто вернуться с нее. Если нет, вам нужно установить некоторые переменные флага и вырваться из циклов. – Navan

0

Ok ребята, я решил проблему так:

L = [1 2 2 3]; 
N = 3; 
sumToN = 0; 
Ret = [0 0]; 

for i=1:numel(L); 
    for j=1:numel(L); 
    if i<j && L(i) + L(j) == N; 
    sumToN = [L(i) L(j)]; 
    end 
    end 
end 
if sum(sumToN) == N; 
    display(sumToN); 

else 
    display(Ret); 
end 

Но, даже если результат отображается только один, количество шагов, выполняемых в цикле for, не изменяется.

1

Давайте немного разобьем вашу программу. Первое, что я собираюсь сделать, это изменить переменные цикла от i, j до a, b, из-за этого: Using i and j as variables in Matlab.

Далее я буду смотреть на линии

if i<j; 

Мы всегда хотим, чтобы это было так, поэтому давайте сделаем это таким образом. (Переключение на a, b сейчас) ...

for a=1:numel(L)-1 
    for b=a+1:numel(L) 

Обратите внимание, что петля для b Теперь начинается со значения a+1. Так bвсегда больше, чем a, и нам больше не нужна эта проверка. Я также закончил цикл a в numel(L)-1, потому что нет элемента после L(numel(L)) для b, и мы хотим убедиться, что a+1 всегда действителен.
(Также обратите внимание, что я удалил точку с запятой на концах строк. Они не нужны и эффективно добавляют пустую строку в цикл.)

Теперь мы готовы, чтобы увидеть, если L(a), L(b) пара добавляет к N и если да, то установите наш возвращаемое значение:

if L(a)+L(b) == N 
    sumToN = [L(a) L(b)]; 

Если вы хотите, чтобы значение, отображаемое здесь, либо сделать:

display(sumToN); 

или оставить точку с запятой от выполнения задания sumToN = ...

Если мы внутри if и мы назначили возвращаемое значение, мы хотим прекратить искать другие ответы. В этот момент я собираюсь предположить, что вы должны писать автономную функцию и что это все, что должна выполнять функция. Чтобы закончить циклы (и, действительно, любую дальнейшую обработку функции), вы должны использовать return сразу после назначения. Это делает вложенные циклы выглядеть следующим образом:

sumToN = [0 0]; 
for a=1:numel(L)-1 
    for b=a:numel(L) 
     if L(a)+L(b) == N 
     sumToN = [L(a) L(b)]; 
     return 
     end 
    end 
end 

Здесь вы можете добавить свою инициализацию для L и N в начале и disp(sumToN); в конце для сценария, или вы можете сделать полноценную функцию с функцией декларации и другой end:

function sumToEnd = summy(L,N) 
    <all the stuff above goes here> 
end 

вещи немного сложнее, если это является частью более крупного сценария, который вы не хотите, чтобы полностью выйти, как только вы найдете пару, но она по-прежнему вполне возможно. (Вам нужно будет использовать break два раза, каждый раз выходящий из одного цикла, в сочетании с логической переменной, чтобы сообщить вам, когда нужно сломать.)

+0

Алгоритм выше не возвращает пустую пару, если условие «L (a) + L (b) == N'не выполняется ... – james42

+0

@ ale42 Это для меня. 'sumToN = [0 0];' означает, что '[0 0]' будет возвращен, если ничего не перезапишет его. Вы пытались запустить его? – beaker

+0

Да. Теперь он работает, и код является более гибким. Я добавил beisplay (sumToN) «прямо перед возвратом в цикле« for », как раз перед« возвращением »и в конце программы, вне цикла. Благодаря! – james42

Смежные вопросы