2017-02-18 15 views
5

Вопрос, как упоминалось выше, имеет следующий вид: Если заданы два целых числа x1 и x2, найдите другое целое число x3, которое отличается от x1 и x2, не используя ключевое слово if.Для двух целых чисел найти третье целое число, отличное от данных двух, без использования, если statment

Мое решение основано на битовых действиях на целых числах плюс на то, что XOR между двумя битами будет возвращать 1 тогда и только тогда, когда два бита не равны.

Действительно ли это решение? Можете ли вы найти лучшее решение? Конечно, время ожидания и потребление памяти должны быть максимально хорошими.

Примечание: тройные операции и сравнения (.! - т.е. =, ==) являются, а также не допускается

Спасибо заранее,

Guy.

Мое решение:

int foo(int x1,int x2) 
{ 
    // xor 
    int x3 = x1^x2; 

    // another xor 
    x3 = x3^x2; 

    // not 
    x3 = ~x3; 

    return x3; 

} 
+1

Что у вас есть '~ (x^y^y)', который является просто '~ x', поэтому он не работает, если' y = ~ x'. – Ryan

+2

'z = x^y; z = z^y' означает 'z = x', тогда' z == ~ x' может быть '~ x == y' ??? –

+1

Вы можете использовать скрытые 'if', используя мультипликативные свойства:' a = c * x + (1-c) * y', который дает вам x, если 'c == 1' и y, если' c == 0'. Может быть, это каким-то образом? –

ответ

4

Преобразование мои комментарии к ответу:

Что у вас есть ~(x^y^y), который только ~x, поэтому он не будет работать, если y = ~x. Один из вариантов, вместо этого, чтобы сделать ряд, который отличается от x1 в положении двое и отличается от х2 в положении из них: (.! Облегчение от (~x1 & 2) | (~x2 & 1) кредита @chux Спасибо)

return ~(x1 & 2 | x2 & 1); 

+3

Что это такое, так это то, что его легко расширить до 3,4, ... integer_width integers. (может быть, не бит знака на не 2). – chux

3

Будучи педантичным, так как они сказали, что не if ключевого слова, то триады должна быть честной игрой ...

return (x1+1 == x2) ? x1+2 : x1+1; 

Конечно, возможно, что это обман. Нет проблем, здесь нет троичной-бесплатной версии:

return x1+1+(x1+1==x2); 

И не волнуйтесь, если вы думаете, что условная еще обман, есть many ways реализовать его с прямой манипуляции с битами.

Обратите внимание, что решение добавления действительно справедливо только для целых чисел без знака, поскольку оно индуцирует потенциал для переполнения подписей (что является UB). Если это вызывает беспокойство, вы можете заменить дополнение другой операцией (например, x1^(1+(x1^1==x2)).

+1

Вы просматриваете регистр флагов с '==', который является неявным 'if'. –

+1

@PaulOgilvie, что не имеет смысла –

+0

М-м, я не понимаю. Любой оператор if должен использовать регистр флагов для получения результата условия, будь то флаг нуля, флаг переноса или любой флаг. Таким образом, наоборот, любое использование регистра флагов подразумевает if. Выражение 'x1 + 1 == x2' использует флаг нуля в тестировании для равенства. –

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