Поменяйте местами целочисленные переменные без использования присваивания - PullRequest
1 голос
/ 12 октября 2010

все! Может кто-нибудь, пожалуйста, помогите мне решить такую ​​задачу. Мне нужно поменять значения переменных без использования каких-либо знаков присваивания. Я попытался сделать это с помощью цикла while, но нигде не могу хранить значения счетчика. Спасибо всем заранее.

Ответы [ 8 ]

7 голосов
/ 12 октября 2010

Вы можете использовать Interlocked.Exchange.

6 голосов
/ 12 октября 2010

Xor-swap использует назначения. Но, возможно, вам разрешено использовать инкремент и декремент (которые, строго говоря, разрешаются до += 1 и -= 1 в C #, но логически они часто считаются разными).

int tmp = 0; // C# complains if we don’t initialize!
while (a-- > 0)
    tmp++;
while (b-- > 0)
    a++;
while (tmp-- > 0)
    b++;

Эта логика иногда используется при анализе примитивных исчислений, таких как формализм программы LOOP. Конечно, эти формализмы не требуют инициализации полей, в противном случае все правило «без присвоения» будет полностью спорным. В строгом исчислении tmp также должно быть инициализировано нулем с помощью цикла:

while (tmp > 0)
   tmp--;

Это будет работать независимо от того, какое значение tmp имело ранее (при условии tmp > 0, что обычно является требованием во всех этих исчислениях: отрицательных чисел не существует).

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

Как отметил @Doc Brown в комментариях, это работает только для (положительных!) Целых чисел - хотя теоретически (еще раз: не в C #!) Это можно сделать для работы с любым типом, который может быть представлен на Von Архитектура Неймана, поскольку все они хранятся в памяти как числа (до некоторой базы).

6 голосов
/ 12 октября 2010

Поскольку целые числа являются неизменными в C #, вы не можете «поменять местами переменные без использования присваивания»;вам нужно как-то переназначить их где-нибудь.Возможно, вы имеете в виду Обмен двух переменных без использования временной переменной ?Или, если вы имели в виду без явного использования =, ответ @Konrad Rudolph - это путь.

4 голосов
/ 12 октября 2010
class Program
{
    private static void Swap(ref int a, ref int b)
    {
        int.TryParse((a ^ b).ToString(), out a);
        int.TryParse((a ^ b).ToString(), out b);
        int.TryParse((a ^ b).ToString(), out a);
    }

    static void Main(string[] args)
    {
        int a = 42;
        int b = 123;
        Console.WriteLine("a:{0}\nb:{1}", a, b);
        Swap(ref a, ref b);
        Console.WriteLine("a:{0}\nb:{1}", a, b);
    }
}
2 голосов
/ 12 октября 2010
int i = 10, j = 20;
i = i + j;
j = i - j;
i = i - j;
2 голосов
/ 12 октября 2010

Имеет ли значение xor-swap?

     x ^= y;
     y ^= x;
     x ^= y;
2 голосов
/ 12 октября 2010

См. Bit Twiddling Hacks , он покажет вам, как сделать это различными способами, не используя назначения.

0 голосов
/ 12 октября 2010

Я не думаю, что это даже возможно в C #.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...