C練習コード-151108

4014 ワード

1.プログラミング実装:
2つのint(32ビット)整数mとnのバイナリ表現の中で、何ビット(bit)が違いますか? 
入力例:
1999 2299
出力例:7
int ce_bin_wei()
{
//unsigned int a=1999,b=2299;
 int a=1999,b=2299;
int i=0;
int sum=0;
for(i=0;i<31;i++)
{
sum+=(a&1)^(b&1);
a>>=1;
b>>=1;
//a/=2;
//b/=2;
}
return sum;
}

==================================
//方法2
#include <stdio.h>
int count_one(int num)
{
int count = 0;
while (num)
{
count++;
num = num&(num - 1);//              1   
}
return count;
}
int main()
{
int n1 = 0;
int n2 = 0;
scanf("%d%d", &n1, &n2);
int num = n1^n2;
int ret = count_one(num);
printf("%d
", ret); system("pause"); return 0; }

2.作成関数:
unsigned int  reverse_bit(unsigned int value);

この関数の戻り値valueのバイナリビットモードは左から右に反転した値です.
次のようになります.
32ビットマシンで25という値には、次のようなものが含まれています.
00000000000000000000000000011001
反転後:(25500136832)
10011000000000000000000000000000
プログラム結果は次のように返されます.
          2550136832
unsigned int reverse_bit(unsigned int value)
{
unsigned int rev_val=0;
int i=0;
for(i=0;i<32;i++)
{
rev_val<<=1;
rev_val+=(value&1);
value>>=1;
}
return rev_val;
}

=============================================
もう一つ
typedef unsigned int uint;
uint reverse_bit(uint value)
{
int i = 0;
uint sum = 0;
for (i = 0; i < 32; i++)
{
sum += ((value >> i) & 1)*pow(2, 31 - i);
}
return sum;
}

==============================================
3.(a+b)/2を用いずに、2つの数の平均値を求める.
#include <stdio.h>
int main()
{
int num1 = 10;
int num2 = 20;
int avg = num1&num2 + (num1^num2) >> 1;

//方法1 num 1&num 2
//①まず同じビット========num 1とnum 2のバイナリの同じ保持で2つの等しい数a 1 a 2を形成するこの2つの等しい数を加算して2で割ると自分の本に等しい

//つまりnum 1&num 2(num 1=(1)十進法=(0001)ここでは単純に表すが、全32ビットnum 2=(3)十進法=(0011)バイナリは書かれていない)
//num 1&num 2=001(0001=(num 1でnum 2に等しい)+0001)/2)
//②さらに同位でない========(num 1^num 2)両数の同位でない(オーバーフローは生じない)右シフト1位は2を除く
//オーバーフローは発生しない
//方法2このような良い理解も同様に溢れていない
//=====================int avg2 = num1 - (num1 - num2) / 2;===================

printf("%d", avg);
system("pause");
return 0;
}
4.データのセットに1つの数字しか表示されません.
他のすべての数字はペアで表示されます.この数字を見つけてください.(ビット演算を使用)
int find_d(int arr[],int len)
{
int i=0;
int temp=0;
for(i=0;i<len;i++)
{
temp^=arr[i];
}
return temp;
}

//==============================================================
==========================================
5、【補強版】
1つの整数配列には2つの数字を除いて、他の数字が2回現れた.プログラムを書いて、この2つの一度しか現れない数字を見つけてください.
[異或演算の性質:任意の数値異或それ自体が0に等しい]
[上記の簡単な問題4の解決策があれば、元の問題に戻ります.元の配列を2つのサブ配列に分けることができます.各サブ配列には、1つのサブ配列のみが含まれています.
1回の数字が現れ、他の数字は2回現れます.このように元の配列を分割することができれば、前の方法でこの2つの1回しか現れない数字をそれぞれ求めることになります.

私たちはやはり最初から最後まで順番に配列の中のすべての数字を異にして、最終的に得た結果は2つの1回しか現れない数字の異種または結果です.他の数字は
2回現れて、異或の中ですべて相殺された.この2つの数字は必ず異なるので、この異或結果は0ではありません.つまり、この結果の数字の
バイナリ表現の少なくとも1つは1です.結果数字で1番目のビットの位置を見つけ,N番目のビットと記す.今、私たちはN位が1かどうかを基準に
元の配列の数字は2つのサブ配列に分かれており、第1のサブ配列の各数字のN番目のビットは1であり、第2のサブ配列の各数字のN番目のビットは0である.(この2つは
数字が違うということは、1の位が違うことを意味します)
]
#include <stdio.h>
//#include <stdlib.h>
int main()
{
int arr[] = {2,2,3,3,-1,5};
int i = 0; 
int result = 0;
int num1=0;
int num2=0;
int count=0;
int len=sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < len; i++)
{
result^= arr[i];
//               
}
//               
count=1;
i=1;  
while(result){  
if((result&i)==1)
{  
break;  
}  
result>>=1;  
count<<=1;  
}  
//               
num1 = 0;  
num2 = 0;  
for(i=0;i<len;i++)
{  
if((arr[i]&count)==0)
{  
num1 ^= arr[i];  
}else{  
num2 ^= arr[i];  
}  
}  
printf("%d    %d
", num1,num2); //system("pause"); return 0; }

5参照先http://z466459262.iteye.com/blog/1125518