いいアルゴリズムっていうか小技を教えて
■ このスレッドは過去ログ倉庫に格納されています
00011 ◆UbLWewsM
NGNG普通は
tmp = a;
a = b;
b = tmp;
みたいにやるところを、
a = a + b;
b = a - b;
a = a - b;
ってやれば余計な変数を使わずに実現する!
みたいなちょっとした小技を教えてください。
見た人が「なるほど」って感動するようなやつを。
0002デフォルトの名無しさん
NGNG0003デフォルトの名無しさん
NGNGウッウッ
0004デフォルトの名無しさん
NGNG0005デフォルトの名無しさん
NGNGそのわりに名前は1か
0006デフォルトの名無しさん
NGNGコンパイルしないスクリプト言語はぜんぶ
そうなんですかね?
0007名無しさん@揚げ足
NGNG0008デフォルトの名無しさん
NGNGつか、
トリッキーなコード
http://pc.2ch.net/test/read.cgi/tech/983191866/
じゃだめなの?
a ^= b ^= a ^= b;
とかあるよ。
0009デフォルトの名無しさん
NGNG最近のやつは内部で中間コードに落としたりしてるから、
関係ないんじゃねーの?
00106
NGNGじゃ中間コードに落とす時点での
速度差があるってことですかね?
0011デフォルトの名無しさん
NGNG遅くなるだろーけど、普通のソースだったら殆ど差なんか出ないだろ。
0012デフォルトの名無しさん
NGNG0013デフォルトの名無しさん
NGNG0014デフォルトの名無しさん
NGNGa b cの中身を指定した順番に簡単に入れ替えれるやつないかな
漏れも今から考えてみるけど。
0015デフォルトの名無しさん
NGNGa = ( a - ( b = ( a = a + b ) - b ) );
0016デフォルトの名無しさん
NGNG>>1を横にしただけだけだけど面白いと思う
0017デフォルトの名無しさん
NGNGだけが1個多いだけだけだけど面白いと思う
0018デフォルトの名無しさん
NGNGhttp://pc.2ch.net/test/read.cgi/tech/1016815283/6-9
のソースが意味不明なんだけど....
動かなかったし
0020デフォルトの名無しさん
NGNGすいません。見てなかった。
つか、Cのソースだったのか....
ハァ...耳(外耳炎)の次は目か...
0021デフォルトの名無しさん
NGNGそれは面白いが、良いアルゴリズムではないよ。
0023デフォルトの名無しさん
NGNG0024デフォルトの名無しさん
NGNG多くの CPU は b=a-bは1命令に落ちないから XOR の方がいいんだよ
0025デフォルトの名無しさん
NGNG0026デフォルトの名無しさん
NGNGb = 7;
while(a > b){a=a-b;}
aに最初の数を入れれば、
最後にはaに余りが入るんじゃないかな。
bは7以外でも可かな?試してないから自信ないけど。
0027デフォルトの名無しさん
NGNGヒント a mod 8 なら a and -8 で代用出来る。
-8 は 2の補数表現として 8bitなら 11111000 ね
002826
NGNG可能な限り誰でもわかるようにわざわざ書いたのに。
待ってて書き直す。
002927
NGNGヒント a mod 8 なら a and 8-1 で代用出来る。
8-1 は 2の補数表現として0000 0111 ね
0030デフォルトの名無しさん
NGNGwhile( a != 0){
if( a >= b ) a-=b;
b = b >>1;
}
0031デフォルトの名無しさん
NGNG自ら宣言する余計な変数は減るかもしれないけど
明らかに遅くなるよ。a = a+bの時点で
a+bを格納するための変数のコンストラクタが呼ばれているから。
わざわざ加算・減算のための関数をよんでるからオーバーヘッド
が発生する。
たとえaもbもただの32bit int 型だったとしてもオーバーフローする
可能性があるしバグ探しで見つかりにくい。
条件式なんかつけたらそれこそ投機実行で死んでくれるからね。
それよりも、値が早く、でるような、よい関数を、考えましょう。
テイラー展開。
003227
NGNGその方が汎用的だね 用意していた答えは
while( a>7 ) a=(a>>3)+(a&7) ; if( a>=7 )a-=7;
このwhile をバイナリ展開すれば もっと早くなるけど
0033デフォルトの名無しさん
NGNGとまってないよ…
それってどんな値でも 0にならないか?
0034デフォルトの名無しさん
NGNG0035間違ってたし
NGNGwhile( a < 7){
if( a >= b ) a-=b;
b = b >>1;
}
0036また間違ってたし
NGNG0037デフォルトの名無しさん
NGNG整数演算ならマトモなコンパイラは関数呼び出しなんてやりません
そして整数演算ならオーバーフローしてもこの演算は必ず復帰しますよ
ってもしかして縦読み?
0039デフォルトの名無しさん
NGNG感じだから途中オーバフローする訳だけど、結果さえ収まっていれば正しく計算出来るよ
0040デフォルトの名無しさん
NGNG単独なら意味ないかもしれないけど
ttp://www.infoeddy.ne.jp/~tensyo/prog/linealgo.htm
小さい方の絶対値を 1/2にして大きい方に足して返すらしい
ihypot(int a,int b)
{
a=abs(a);
b=abs(b);
{ register w=( ( a-b ) >> 31 ) & ( a^b ); /* a>bなら w=0 */
return ( a^w )+( b^w )/2;
}
}
0041デフォルトの名無しさん
NGNG実行速度よりも行数優先で。
5個の変数(配列でも可)を昇順で。
どの言語でも簡単に応用できる程度にね。
0043デフォルトの名無しさん
NGNGvoid SortIntArray(int n, int dt[])
{int i,j:
for(j=0;j<n;j++)
for(i=1;i<n;i++)
{ int w=(dt[i] ^ int[i-1]) & ((dt[i]>int[i-1])*-1) ; //確か 条件式の結果は1か0だったよね?
dt[i]^=w;
dt[i-1]^=w;
}
}
0044デフォルトの名無しさん
NGNGまっ課題としては面白いんだけど、実用的じゃないんだよな。
004543
NGNGprocedure SortIntArray(var dt:array of Integer);
var i,j,w:Integer;
begin
for j:=0 to High(dt)-1 do
for i:=j+1 to High(dt) do begin
w:=(dt[i] xor dt[j]) and ( ord(dt[i]>dt[j])*-1 );
dt[i]:=dt[i] xor w;
dt[j]:=dt[j] xor w;
end;
end;
ord(dt[i]>dt[j])*-1 を 減算してボローを見るアセンブラコードにすれば分岐無しソートになるぞ
0046デフォルトの名無しさん
NGNGその他のアイディアは無しか。
一応私も
#include <stdio.h>
#define sw(a,b) (a^=b,b^=a,a^=b)
int d[5]={42,11,56,34,22};
int main(){
int i,j;
for(i=4;i>0;i--)for(j=0;j<i;j++)if(d[j]>d[j+1])sw(d[j],d[j+1]);
for (i=0;i<5;i++)printf("%d\n",d[i]);
}
gccで検証
0047デフォルトの名無しさん
NGNGvoid SortIntArray5(iint dt[5])
配列サイズは固定で
0048デフォルトの名無しさん
NGNGメモリアクセスコストが大きいなら比較して 5!=120通りに分岐するのが最速だし
そんなコード見たい?
0049デフォルトの名無しさん
NGNG( (dt[1]<<16)&0xffff0000 )+
( (dt[2]<<16)&0xffff00000000 )+
( (dt[3]<<16)&0xffff000000000000 )+
( (dt[4]<<16)&0xffff0000000000000000 );
dt[0]=kotae[key][0];
dt[1]=kotae[key][1];
dt[2]=kotae[key][2];
dt[3]=kotae[key][3];
dt[4]=kotae[key][4];
kotae_table[100000000000000000000][5]={
.....
};
0050デフォルトの名無しさん
NGNG( (dt[2]<<32)&0xffff00000000 )+
( (dt[3]<<48)&0xffff000000000000 )+
( (dt[4]<<64)&0xffff0000000000000000 );
に訂正
0051デフォルトの名無しさん
NGNG0052デフォルトの名無しさん
NGNGレジ10回通れば消費税がかからないよ。
0053デフォルトの名無しさん
NGNG示唆に富んでるなぁ…
葉書10枚を送れば500円かかるけど、
その葉書10枚を封筒に詰めて送れば500円はかからないよ。
0054デフォルトの名無しさん
NGNG某クロスワードの雑誌にはその方法を使うとよいと書かれているね。
0055デフォルトの名無しさん
NGNG0056デフォルトの名無しさん
NGNG懸賞とか。
0057デフォルトの名無しさん
NGNGつまり n が2のベキかどうかを高速に判定する方法
・・・これはスレも立ったことある問題だから知ってる人は多いかな?
0058デフォルトの名無しさん
NGNG0059デフォルトの名無しさん
NGNGint b=0;
while( a!=0 ){
if( a&1 ) b+=1;
a = a >>1;
}
return( b==1 ); //BOOLで返すの作ったこと無いので間違ってるかも
}
0060デフォルトの名無しさん
NGNG0061デフォルトの名無しさん
NGNG0062デフォルトの名無しさん
NGNG0063デフォルトの名無しさん
NGNG0064デフォルトの名無しさん
NGNGint b=a;
a |= (a>>16);b += (b>>16);
a |= (a>>8);b += (b>>8);
a |= (a>>4);b += (b>>4);
a |= (a>>2);b += (b>>2);
a |= (a>>1);b += (b>>1);
return( (a==b) || (a==0) );
}
0065デフォルトの名無しさん
NGNG0066もーわけわからん
NGNG0067デフォルトの名無しさん
NGNGじつは >>57 そのものがヒントになってるよ
もっとヒント出すと 逆に a% n == a &(n-1) になる nが必ず2のベキであるaの値は?
0068ひよこ
NGNG>>1のですら実験してみるまでわけわかんなかった。
a^=b^=a^=bもやっと意味わかった程度。
ビット演算なんかぜんぜんわからん。
みんなどーやって考えてるの。
よいページあったら教えてー。
0069デフォルトの名無しさん
NGNGつーか分からないんだったら素直に普通のコーディングしてれ。
007067
NGNG0071デフォルトの名無しさん
NGNGreturn (a > 0 && (a | (a - 1)) == (a + (a - 1))) ? 1 : 0 ;
答えはもっと簡単?
0073デフォルトの名無しさん
NGNGa & (a - 1)は、他にも0になる値がありそうな気がして、
何となく避けてしもた。んなこたない
0074デフォルトの名無しさん
NGNG多倍長計算のクラスをC++で組むときには
void Change(HOGE hoge1,HOGE hoge2);
みたいのを作っとくと後々便利ですかね?
hoge1 = temp;hoge1 = hoge2;hoge2 = temp;とかやると
メモリ確保とメモリコピーに無駄に時間がかかりそうなので。
0075デフォルトの名無しさん
NGNGスレの趣旨とは違うガナー
0076デフォルトの名無しさん
NGNGttp://research.microsoft.com/~hollasch/cgindex/math/pythag-root.txt
0077デフォルトの名無しさん
NGNG多倍長というかある程度のサイズのオブジェクトはポインタで管理し、インスタンスは動かさないのが基本
0078デフォルトの名無しさん
NGNG007974
NGNGCommutation(HOGE hoge1,HOGE hoge2);
でかまいませんか?
0080デフォルトの名無しさん
NGNG0081デフォルトの名無しさん
NGNGcommutation にも確かに交換という意味はあるけど、
プログラムで使ってるの見たことない。
0082デフォルトの名無しさん
NGNG自力でそういうことを考えたのは偉いと思う。
だけど、C++の良書にはそういうテクニックは普通に
載ってる。買って読もうな(推薦図書スレに行くべし)。
ちなみに、ホントに交換したいなら、
void Hoge::swap(const HOGE& hoge);
というメンバ関数にするのが一般的。
0083デフォルトの名無しさん
NGNGconst相手のswapできるのかと
0085デフォルトの名無しさん
NGNGMSB LSB
R:5 G:6: B:5
でR,G,Bのそれぞれ平均を求める計算
0086デフォルトの名無しさん
NGNG0087デフォルトの名無しさん
NGNGttp://www.geocities.co.jp/SiliconValley-PaloAlto/5989/trans01.html
とかで565でやってたから 565が多いのかと思った
じゃ 555で
0088デフォルトの名無しさん
NGNGa=a xor b
b=a xor b
a=a xor b
オーバーフローしない処理
0089デフォルトの名無しさん
NGNG0090デフォルトの名無しさん
NGNGそれってアルファブレンドじゃなくて単なる半透明
0091デフォルトの名無しさん
NGNG0092デフォルトの名無しさん
NGNGR,G,Bを その2^ビット位置として
r1*R+g1*G+b1*B が1ワードだとすると0<=α<=1の範囲なら
(r1*R+g1*G+b1*B)*α+(r2*R+g2*G+b2*B)*(1-α)
つまり、ビット位置に関係なく一つのワードとして処理すればいいんだよ
009392
NGNGつまり
int HarfBlend(int a, int b){ return ((long)a+(long)b)/(long)2;}
と書いておけば 565でも555でも888でも正しく動くという事
0094デフォルトの名無しさん
NGNG桁上がりが起きたら破綻するから駄目
0095デフォルトの名無しさん
NGNG0096デフォルトの名無しさん
NGNG論理演算でやるなら
888なら mask=(not ((a xor b) and $010101)) とマスクビットを用意して
return ( (mask and a)+(mask and b) )>>1;
0097デフォルトの名無しさん
NGNG0098デフォルトの名無しさん
NGNGttp://www.emit.jp/prog/prog_b.html
0100デフォルトの名無しさん
NGNG0101デフォルトの名無しさん
NGNG■ このスレッドは過去ログ倉庫に格納されています