呵呵,好像我来这里这么久了都没有用分的机会,现在来散一下
早前在这个区和.NET Framework区看到两次这个题目了,都没看到有人给出能处理极端情况的答案,所以再来提一次。已知:
int a, b;
并已赋值,值的唯一限制是int.MinValue<=a,b<=int.MaxValue,所有极端情况均有可能
例如 a = 2147483647, b = 2147000000
又或 a = -2147483600, b = -2147483640
又或 a = 2000000000, b = -2000000000
当然也包括 a = 0, b = 0 (-_-)现在要将a,b的值交换没有任何导入的命名空间(即如果你要用类,必须从System开始写起)
没有任何辅助的方法(即如果你要辅助方法,你要自己写)
除了a和b没有其它已经声明的字段或参数或局部变量,并且不能再声明任何变量!求最短的、编译可以通过的、所有情况下都能达到目的的 C# 代码我已知的最短的代码是 ## 字节,看能不能打破这个纪录(##: 为激起挑战欲,我不便公开,反正是个某些国家看来不吉利的数字)2天之内结用来测试的代码:
class Program
{
    static void Main()
    {
        int a = 1234567890, b = 987654321;
        /**************************\
         * 将你的答案填入下面两个斜杠内 *
         *//*
         * 将你的答案填入上面两个斜杠内 *
        \**************************/
        System.Console.WriteLine("a={0},b={1}", a, b);
        System.Console.ReadLine();
    }
}给分标准:
1)一旦出现少于##个字节的正确答案,100分全给;
2)两天之内没有达到(1)的话,等于##字节的第一个正确答案100分;
3)没有达到(2)的话,根据回复所体现的钻研精神和创意分配100分祝大家斗得开心,玩得愉快 ^o^提示:嗯,提示已经出现在本贴里!

解决方案 »

  1.   

    a = 1;
    b = 2;a = a + b;
    b = a - b;
    a = a - b;搂主给分吧。
      

  2.   

    a^=b^(b^=a^b);
    肯定是它,但问题是他是13位,也就是现在还没要破的记录!看谁能少于13位吧
      

  3.   

    int a=3,b=5;
    a-=b-=a+=b;
    // a^=b^(b^=a^b);
    Response.Write("a="+a+"<br>");
    Response.Write("b="+b+"<br>");
    测试通过
      

  4.   

    a-=b-=a+=b;这个肯定不对,会溢出。
      

  5.   

    收回上面的字 
    int a = 1234567890, b = 987654321;
    失败 没考虑周全 又菜鸟了一回 唉
      

  6.   

    Ivony()  发公布答案了
    用^反复试 都是太长
      

  7.   

    已经给了提示,不用异或。再给个提示,这就是典型的利用运算符优先级和运算顺序实现的一个算法:while( str != (str = str.Replace("  ", " ") );将所有连续的空格替换成一个,利用的正是运算符的优先级别和顺序。
      

  8.   

    公布答案,当当当当:b=a+(a=b)*0
      

  9.   

    在对b赋予a值的时候,在没有改变a和b的值的时候同时对a赋予b的值。是不是这样的?
      

  10.   

    这是充分利用运算符的优先级别和顺序做出来的,首先要了解两件事。赋值运算符的优先级别是很低的,并且运算顺序是从右至左。
    也就是说b = a + ( a = b ) * 0会先算右边的a + ( a = b ) * 0。加法运算符的优先级别比赋值运算高,并且运算顺序是从左至右。
    所以a + ( a = b ) * 0会先计算左边的a,然后再计算( a = b ) * 0,就是这个顺序使得a的值可以暂存。
    剩下的事情就是把a=b这个表达式的值给消掉了,方法也很简单,两个字节搞定,*0。
      

  11.   

    设A=1。B=2
    当(a=b)的时候
    b=a+(a=b)*0第一个a是1吗?为什么?
      

  12.   

    b=a+(a=b)*0第一个a是1吗?为什么?是1,原因是C#的运算顺序确实是这样。
      

  13.   

    b=a+(a=b)*0  
    b=a+(a=b)-a  
    b=a+(a=b)-b 
    上面两个结果一样,效率是否是下面那两个高点?
    b=a+(a=b)-a 
    b=a+(a=b)-b 
      

  14.   

    b=a+(a=b)-a 
    b=a+(a=b)-b 
    溢出
      

  15.   

    自己写的程序倒是可以这样交换两个数值,如果用Reflector反编译的话会出错的。呵呵。但是如果在项目中这样用,估计会被review代码的老大骂死。
      

  16.   

    xchg下不行吗?,何必乘过来乘过去.
      

  17.   

    怎么这么快就11字节了啊,郁闷,我好不容易想出一个12个字节的,
    不知道有分没有?int a = 2147483647;
    int b = -2147483640;
    a=b|a&~(b=a);
      

  18.   

    中国人就是这么sb,每年的程序大赛上都是中国和俄罗斯那将,可是就是没有出一个
    像微软,google样的公司,因为他们一天到晚都在想法考试自己,以为这样智力就高了,
    从sb的王小丫,再到sb的忘了那个叫什么了,反正呵呵...
      

  19.   

    呵呵,来结帖不过大家似乎都太钻于“一个语句”我只限制了不能用第三个变量,没有限制不能用多个语句我之前所知道的13字节(即字符;用UTF8编码=13字节)长的答案是:
    b^=a^=b;a^=b;注意:要使它能够编译,分号也是必须的,所以上面11个字节、12个字节的答案,其实是12字节、13字节,不过 Ivony 的12字节的答案:
    b=a+(a=b)*0;
    完全符合要求,所以根据我原来设定的给分方法,Ivony获100---------------------------其实我顺便还想找的东西是最小化CPU用量,传统方法:c=a;a=b;b=c 用了3次提取,3次赋值;
    异或方法:b^=a^=b;a^=b 用了4次提取,3次运算,3次赋值,虽然省掉了一个变量,但是比较浪费性能
    而Ivony的方法却只有2次提取,2次运算,2次赋值
    我记得的是赋值操作比运算慢,所以我猜2/2/2跟3/0/3大概是同一个级别的yuanarea(Sail before)的方法 a=b|a&~(b=a); 也比全异或少了1次提取1次赋值,所以也很值得我崇拜,不过你的语句13字符长,被Ivony打下去了XD
      

  20.   

    b=a+(a=b)*0;
    这个答案不仅仅是代码最短的,也是效率最高的,因为C#的编译器非常之聪明给它做了优化,便以出了下列IL,从IL的角度来说,都是最简表达了,没有比他更短、更简洁的IL。
      IL_000c:  ldloc.0//第一个变量压栈,即把a压栈。
      IL_000d:  ldloc.1//第二个变量压栈,即把b压栈。
      IL_000e:  stloc.0//出栈赋值给第一个变量,即把栈顶的值弹出并付给a(因为栈是先进先出的,所以这个值是b的值)
      IL_000f:  stloc.1//出栈赋值给第二个变量,即把栈顶的值弹出并付给b。
    其实根本没有运算,就压栈两次出栈两次,应该不会有比这更快的了。
      

  21.   

    便以出了下列IL => 编译出了下列IL
      

  22.   

    老兄这个是不会 溢出 的
    你可以好好研究下为什么了`~~!petshop4() ( ) 信誉:100  2006-7-24 13:39:54  得分: 0  
    b=a+(a=b)-a 
    b=a+(a=b)-b 
    溢出  
     
      

  23.   

    int b=2000000000,b=1000000000
    b=a+(a=b)-a =》b=(a+(a=b))-a
    当10亿+20亿等于多少?
    INT最大不过2147483647
    不要以为结果没错就不是溢出
      

  24.   

    a = 1;
    b = 2;a = a + b;
    b = a - b;
    a = a - b;搂主给分吧。
      

  25.   

    这个帖子如果没有Ivony 的回帖,真的就是一文不值,楼主自己的答案纯属钻牛角,一点意义都没有.
      

  26.   

    没有玩过c#,
    但是这样的语法解析让我感觉到恐惧,
    b=a+(a=b)*0;
    这样的语句执行过程在 c/cpp 中如下
    (为了说明,old_a或old_b代表 a或b的原值。)
    a=b ==> a = old_b;
    (a=b)规约后令其为 R1, 其值为old_b;同时a的值也是 old_b
    R1*0规约后令其为R2 值为0
    a+R2 ==> old_b + R2   规约后令其为R3 ,其值为 old_b
    b=R3 规约后令其为 R4,其值为 old_b ,同时 b的值也是old_b
    所以,在c/cpp中
    b=a+(a=b)*0; 地执行结果是 b和a都是old_b。
    而不是 swap;在c/cpp中,下面的例子应该是写法最简的(在devcpp中运行通过)。#include <cstdlib>
    #include <iostream>using namespace std;int main(int argc, char *argv[])
    {
        int a ,b;
        a= 5; b = 6;
        printf("\n %d ,%d ",a,b);    
        b^=a^=b^=a;
        printf("\n %d ,%d ",a,b);
        system("PAUSE");
        return EXIT_SUCCESS;
    }效率最高的做法如果涉及内存变量的交换的话可能是如WYlslrt(WY.lslrt) 所说。
    用xchg示意代码如下。mov ax,a
    xchg ax,b
    mov a,ax但也不一定,具体还要看厂家的实现的该指令的指令周期。如果不涉及内存变量,而是两个寄存器变量的话,那么b^=a^=b^=a; 绝对是最快的。
    在寄存器间的操作和在内存中的操作决定不是一个等级的。
    而且那种做法优点还在于不借助其他寄存器或变量。是目前历史上最优的做法。
    虽然没有用过.net,但Ivony() 的解释中,明显的也用了第三方变量,而且用了两个,
    呵呵,两次的压栈,和申明两个变量无疑。也就是说需要至少两次进出栈的,
    也就是说汇编指令应该如下push a,
    push b,
    pop  b,
    pop  a,
    作了4次访存操作.........
      

  27.   

    不知道为什么,C#下可以正确,但.net的C++下b=a+(a=b)*0; 的结果就成了 b=2,a=2本来受启发想到可以这样
    b=(a,a=b)
    没想到调试不成功,难道C#已经把“,”运算符去掉了?
      

  28.   

    如果真的在程序里面这样写的话,基本上找不到工作的。
    现在的公司都要求TeamWork的,这样的代码,你让别人怎么改,谁敢改。
    特别是日本企业,这样的代码,肯定要被指摘的。
    如果本来就是计算机天才的话,研究一下这个还是支持的。
    如果不是Coding狂人的话,有时间去研究一下OOP可能更有意义!
      

  29.   

    To sjjf(水晶剑锋)xchg肯定是不能用于C#,因为C#顶多能直接写IL代码却绝无可能写汇编。
    但这种行为是被严格定义的,可以在C# 语言规范 1.2版,第7.2章节中找到:表达式中的操作数从左到右进行计算。例如,在 F(i) + G(i++) * H(i) 中,F 方法是使用 i 的旧值调用的,然后 G 方法也是使用 i 的旧值进行调用,最后 H 方法使用 i 的新值调用。这与运算符的优先级无关。尽管写这么BT的代码并不是推荐的,但这条语法规范确实能帮我们省掉一些代码,如典型的:
    while( str != ( str = str.Replace("  ", " " ) );这在C++中也是有可能得不到预期的结果的。
      

  30.   

    phommy(顽石宫主) ( ) 信誉:100  2006-07-25 15:42:00  得分: 0  
     
     
       不知道为什么,C#下可以正确,但.net的C++下b=a+(a=b)*0; 的结果就成了 b=2,a=2本来受启发想到可以这样
    b=(a,a=b)
    没想到调试不成功,难道C#已经把“,”运算符去掉了?因为()的优先级最高(a=b)时a已经等于2了,因此最后就成了b=2+0;
    所以C#这个语法优先级挺奇怪,一般都是()优先级最高。
    因此一开始我还以为Ivony()的b=a+(a=b)*0这句话最后执行结果是a和b都等于2。
      
     
      

  31.   

    回一下这个问题:“没想到调试不成功,难道C#已经把“,”运算符去掉了?”C#里唯一可以用 "," 作为“同一语句内进行多次运算”的地方是 for((1); (2); (3)) 里面的(1)和(3)然后再回一下一些声音其实我本身的知识很有限,我都是看网上其他人的文章的,例如a^=b;b^=a;a^=b;这个,看的就是 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncode/html/secure09112003.asp 这里的最后一部分
      

  32.   

    争论些没用的,题目限制不够
    应该还考虑硬件性能,这种题只有指定了CPU种类和程序平台被才有实际价值,
    一旦被编译器优化,自己的代码写成啥样都一样.
    而且字节短有什么用,效率高才是重要的,若是没有乘法指令集的CPU(比如6502),*0反而会慢
      

  33.   

    lvony 好, C# 强
    b = a + (a = b) * 0; 实际执行的机器指令只有
    00000015  mov         ebx,dword ptr [edi] 
    00000017  mov         eax,dword ptr [esi] 
    00000019  mov         dword ptr [edi],eax 
    0000001b  mov         dword ptr [esi],ebx 
    MS的编译器优化技术都出神入化了.
      

  34.   

    如果是实际应用中,可能不会优化这么好,因为还有其它的变量,不一定有足够的寄存器可用~关于对b = a + (a = b) * 0; 的编译,我觉得C#比C/C++的理解更符合我的理解,C#的计算顺序更好一点。
    楼上有同志说()优先级最大,固然没错,但是单独的一个变量,比如a,也是一个表达式;在表达式“a+(b+c)”,不应该先计算(),应该先计算a的值(虽然实际上只是取个变量而已),
      

  35.   

    b=a-(a=b)*0,太经典了,从来没这么想过。学习。