代码之家  ›  专栏  ›  技术社区  ›  cakeforcerberus

我的字符串反转函数有什么问题?(C)

c#
  •  1
  • cakeforcerberus  · 技术社区  · 16 年前
    char[] a = { 'o', 'r', 'a', 'n', 'g', 'e' };
    
    for (int i = 0; i < a.Length/2; i++)
    {        
      a[i] = (char)(((uint)a[i])|((uint)a[a.Length-(i+1)]));
      a[a.Length-(i+1)] = (char)(((uint)a[i])^((uint)a[a.Length-(i+1)]));
      a[i] = (char)(((uint)a[i])^((uint)a[a.Length-(i+1)]));
    }
    

    我知道如何使用标准的.NET功能和临时变量来实现这一点。我只是好奇,在上面的例子中,我做了什么特别的错误,导致它在以下工作正常时不工作:

    int a = 5;
    int b = 10;
    
    a = a | b;
    b = a ^ b;
    a = a ^ b;
    

    上面的字符串版本不是一系列的吗?

    6 回复  |  直到 16 年前
        1
  •  6
  •   v3.    16 年前

    呵呵,没有OR/XOR/XOR交换,应该是“三重XOR”交换。

    int a = 8, b = 10;
    a ^= b;
    b ^= a;
    a ^= b;
    

    我不明白你为什么要用它(除了新奇的价值)

        2
  •  3
  •   Smashery    16 年前

    它不起作用的原因是你用了一个不好的例子。不能使用或然后使用xor再使用xor交换两个值。它只在您的示例中起作用,因为5和10没有共同点,所以第一个或不破坏任何信息:

    a = 0101 #5
    b = 1010 #10
    # step 1 (OR into a)
    a = 1111
    b = 1010
    # step 2 (XOR into b)
    a = 1111
    b = 0101
    # step 3 (XOR into a)
    a = 1010 #10
    b = 0101 #5
    

    但是,如果它们有任何共同点,就不起作用了——让我们试试13和10:

    a = 1101 #13
    b = 1010 #10
    # step 1 (OR into a)
    a = 1111
    b = 1010
    # step 2 (XOR into b)
    a = 1111
    b = 0101
    # step 3 (XOR into a)
    a = 1010 #10
    b = 0101 #5
    

    注意,我们现在仍然有值5和10,即使我们从13和10开始。你要找的是三次XOR交换:

    a = 1101 #13
    b = 1010 #10
    # step 1 (XOR into a)
    a = 0111
    b = 1010
    # step 2 (XOR into b)
    a = 0111
    b = 1101
    # step 3 (XOR into a)
    a = 1010 # 10
    b = 1101 #13
    
        3
  •  2
  •   Rick C. Petty    16 年前

    它具有破坏性(因为按位或)。为什么不在循环中使用一个临时变量而不是独占的ORS:

    int tmp = a[i];
    a[i] = a[a.Length-(i+1)];
    a[a.Length-(i+1)] = tmp;
    

    作为对第二部分的回答,您在binary中所做的是:

    a = 0101;
    b = 1010;
    a = 0101 | 1010 === 1111;
    ...
    

    当你或两个值在一起时,你会破坏原来的数字。它与5&10一起工作,因为两个数字之间没有共同的位。当您对以下内容执行此操作时:

    a = 0110;  // 6 (base ten)
    b = 1010;  // 10 (base ten)
    a = a | b; // this is now 1110, or 14 (base ten)
    

    您不能再恢复6和10,因为或是一个不可逆的操作。独家或可逆。

        4
  •  1
  •   David    16 年前

    很抱歉,如果这不是你问题的重点,那就说:

     char[] a = { 'o', 'r', 'a', 'n', 'g', 'e' };
     a = Array.Reverse(a)
    

    我错过什么了吗?

        5
  •  1
  •   Noldorin    16 年前

    其他人已经指出了使用XOR操作的正确解决方案…这不是一个确切的答案,但我想我会告诉你 Interlocked.Exchange 方法非常适合这种任务。(它将交换作为一个原子操作执行,因此可以跨线程工作,尽管这在这里似乎无关紧要。)不过,我几乎总是认为它是交换两个变量的最简单/最优雅的解决方案。

    下面是一个如何将它与您发布的代码一起使用的示例。

    char[] a = { 'o', 'r', 'a', 'n', 'g', 'e' };
    
    for (int i = 0; i < a.Length/2; i++)
    {        
        a[a.Length-(i+1)] = Interlocked.Exchange(ref a[a.Length-(i+1)], a[i]);
    }
    

    希望有帮助,即使这不是你问题的具体答案…

        6
  •  0
  •   bytebender    16 年前
    List<char> characters = new List<char>();
    
    characters.AddRange("string".ToCharArray());
    
    characters.Reverse();
    
    string reversed = new string(characters.ToArray());