C语言作业01 最大公因数 斐波那切数列 Hamming Weight 位运算

Task 2: GCD(A,B)

这个task要求我们获取两个数(均小于等于10000000)的最大公约数,因此我使用了辗转相除法。

#include<stdio.h>

int main(){
    int A=0, B=0, C=0;
    printf("input two integers:\n"); 
    scanf("%d %d", &A, &B);//获得两个输入的数值
    while (B > 0)//当余数为0时截止循环
  {
    C = A%B;//取余数
    A = B;//A取除数的值
    B = C;//B取余数的值
  }
    printf("The GND of A and B is %d", A);
    return 0;  
}

Task 6: Fibonacci sequence

这是代码,我选择用递归的方式进行计算。

int addition(N)
{
    if (N > 1)
    { //根据斐波那契数列的性质,第N个数等于第N-1个和第N-2个数的和
        return addition(N-1)+addition(N-2);       
    }
    else if (N == 1)//根据规定,斐波那契数列的第一个数为1
    {
        return 1;
    }
    else if (N == 0)//为了保证准确性,设置第0个数为0
    {
        return 0;
    }   
}
int main()
{
  int N = 0, res = 0;
  printf("Input an integer positive:");
  scanf("%d", &N);
  res = addition(N);
  printf("The %dth Fibonacci Number is %d",N,res);
  return 0;
}

同时我也写了迭代方式的代码,并获得了同样结果;

#include <stdio.h>

int main()
{
    int n=0,count=1,num1=0,num2=1;
    printf("Input a positive integer:");
    scanf("%d",&n);
    while (count<n)//用来计数做了多少次递归
    {
        num2 = num2 + num1;//获得数列的下一个数
        num1 = num2 - num1;//保存上一个数
        count++;
    }
    printf("the %dth number is %d",n,num2);
    return 0;
}

Task 4: abs(n)

本题要求使用位运算来求一个整数n的绝对值。

一个整数默认位数为32位,因此按位向右移31位后,即可获得该数的符号,即0为正数,-1为负数。若x为正数,y就为0,xy就还是x本身(因为10=1,0^0=0);若x为负数,y就为-1,而与-1异或相当于取反,再加上1(即减去-1)即获得负数的绝对值。

#include <stdio.h>

int main()
{
   int x,y;
   printf("Input an integer:");
   scanf("%d", &x);
   y = x >> 31;//获取x的符号,整数或者负数
   y = (x ^ y) - y;//使用按位异或来进行获取
   printf("The abs of x is %d",y);
   return 0 ;
}

Task 5: m o d ( m , 2 n ) mod(m,2^n) mod(m,2n)

本题要求使用位运算,求 m o d ( m , 2 n ) mod(m,2^n) mod(m,2n) 的值。

首先根据输入的 m , n m,n m,n通过位运算 1 < < n 1<<n 1<<n 获得 2 n 2^n 2n在二进制中的表达式,该数-1则获得了由n个1组成的数。

m = 17 , n = 3 m=17,n=3 m=17,n=3为例,

第一步我们通过按位向右获得了 i = 1000 i = 1000 i=1000 m = 10001 m=10001 m=10001

随后我们通过 i − 1 = 111 i-1=111 i1=111,并根据按位与获得了 l = 00001 l=00001 l=00001

#include <stdio.h>

int main(){
   int m,n,l;
   printf("Input two integers:");
   scanf("%d %d", &m, &n);
   int i = 1 << n;//获得2^n对应的二进制值
   l = m & (i-1);//获得l中第i位无法被2的i次方整除的部分
   printf("The mod is %d", l);
   return 0;
}

Task 7 Hamming Weight

这是我的代码,在代码中我使用了按位与来进行1的统计。因为使用可以将 x = x & ( x − 1 ) x=x\&(x-1) x=x&(x1)二进制表达式中最右边的1去掉。以 x = 20 x=20 x=20为例:

x x x的二进制表达式为 00010100 0001 0100 00010100 , x − 1 = 00010011 x-1 = 00010011 x1=00010011, x & ( x − 1 ) = 00010000 x\&(x-1)=00010000 x&(x1)=00010000 这样就去掉了最右边的1。而循环的终止条件为 x x x 中的所有1都被去掉,此时 x = 0 x=0 x=0.

#include <stdio.h>

int main()
{
    unsigned int x,count=0;//x为输入数字,count用来计数
    printf("Input an integer:");
    scanf("%d",&x);
    while (x>0)//终止条件为x=0
    {
        x = x&(x-1);//去掉最右边的1
        count++;//进行计数,没去掉一个1,count会加1
    }
    printf("There are %d one.",count);//打印结果
    return 0;
}

Task 8 Grial(n)

本题与上面一题相似,在代码中使用按位或来进行统计。因为使用可以将 x = x ∣ ( x + 1 ) x=x|(x+1) x=x(x+1)二进制表达式中最右边的0去掉。以 x = 20 x=20 x=20为例:

x x x的二进制表达式为 10100 1 0100 10100 , x + 1 = 10101 x+1 = 10101 x+1=10101, x ∣ ( x + 1 ) = 10101 x|(x+1)=10101 x(x+1)=10101 这样最右边的0就变成了1。而循环的终止条件为 x x x 中的所有0都被去掉,此时按位取反后   x = 0 ~x=0  x=0.

但是要注意一点:一个Unsigned Int默认是32位的,因此根据之前的判断条件,最左边的1前面的0也会被记入,因此我们还需要一个循环来计算该数字的实际位数并做一步减法,因此我们使用了>>每按位向右一次计数一次,知道x变成0.

#include <stdio.h>

int main(){
    unsigned int x,y,count1=0,count2=0;
    printf("Input an integer:");
    scanf("%d",&x);
    y = x;
    while (~x != 0)//用来计数x中0的个数,当x每位都为1时截止
    {
        x = x|(x+1);//把最右边的0变成1
        count1 ++;//计数1
    }
    while (y != 0)//用来计数x的有效位数
    {
        y = y>>1;//按位向右
        count2 ++;//计数1
    }
    printf("There are %d zeros.",count1+count2-32);//最终用所有的0减去有效位数前的0的个数
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值