练习题(1)

给定一个大小为N的数组arr []。任务是找到所有数组元素的数字之和,其中包含偶数个1,这是它们的二进制表示。
例子:
输入: arr [] = {4,9,15}
输出: 15
4 = 10,它包含奇数1的
9 = 1001,它包含偶数1的
15 = 1111,它包含偶数1的
总和=总和数字9和15 = 9 + 1 + 5 = 15
输入: arr [] = {7,23,5}
输出: 10
------------------------------------------------------------------------------------------------------------
下面这个是我写的:

import java.util.ArrayList;
import java.util.List;

public class SumAll {

	/**
	    给定一个大小为N的数组arr []。任务是找到所有数组元素的数字之和,其中包含偶数个1,这是它们的二进制表示。
		例子:
		输入: arr [] = {4,9,15} 
		输出: 15 
		4 = 10,它包含奇数1的
		9 = 1001,它包含偶数1的
		15 = 1111,它包含偶数1的
		总和=总和数字9和15 = 9 + 1 + 5 = 15
		
		输入: arr [] = {7,23,5} 
		输出: 10
	*/
	public static void main(String[] args) {
		int[] arr ={7,23,5}  ;
		List<String> list = new ArrayList<String>();
		for (int i = 0; i < arr.length; i++) {
			String s = Integer.toBinaryString(arr[i]);//将十进制转成二进制
			String[] ps = s.split("");//将字符串转成数组
			int l = 0;
			//判断二进制的转成的数组中有几个1
			for (int j = 0; j < ps.length; j++) {
				if(ps[j].equals("1")){
					l++;
				}
			}
			//如果包含的1 是2的倍数 则计算
			if(l%2==0){
				String[] ps2 = (arr[i]+"").split("");
				//将变成二进制包含1 为偶数的原来的数字拆分个位数添加到集合中
				for (int j = 0; j < ps2.length; j++) {
					list.add(ps2[j]);
				}
			}
		}
		int k = 0;
		//将集合中的数字相加
		for (int i = 0; i < list.size(); i++) {
			k+=Integer.parseInt(list.get(i));
		}
		
		System.out.println("最后的结果="+k);
	}
}

网上的答案:

import java.util.*; 
  
class GFG  
{ 
  
// Function to count and check the  
// number of 1's is even or odd 
static int countOne(int n) 
{ 
    int count = 0; 
    while (n > 0)  
    { 
        n = n & (n - 1); 
        count++; 
    } 
  
    if (count % 2 == 0) 
        return 1; 
    else
        return 0; 
} 
  
// Function to calculate the sum  
// of the digits of a number 
static int sumDigits(int n) 
{ 
    int sum = 0; 
    while (n != 0)  
    { 
        sum += n % 10; 
        n /= 10; 
    } 
  
    return sum; 
} 
  
// Driver Code 
public static void main(String[] args)  
{ 
    int arr[] = { 4, 9, 15 }; 
      
    int n = arr.length; 
    int total_sum = 0; 
  
    // Iterate through the array 
    for (int i = 0; i < n; i++) 
    { 
        if (countOne(arr[i]) == 1) 
            total_sum += sumDigits(arr[i]); 
    } 
    System.out.println(total_sum); 
} 
} 

在网上这个大佬写的例子中发现了 n&(n-1) 不懂 所以百度了一下:
n&(n-1)位运算的妙用 参考:https://blog.csdn.net/nwpu_geeker/article/details/79763511

一、n-1发生了什么

①、二进制数n,n-1后,如果最后一位是0,将向前一位借2,2-1=1。最后一位为1。如果前一位为0,将继续向前一位借2,加上本身少掉的1.则变为1。一直遇到1。减为0.

所以 二进制 xxxx10000-1 = xxxx01111

②、n&n-1

按照上述 n=xxxx10000,n-1=xxxx01111

xxxx10000

xxxx01111

xxxx0000

可以看到将原来的最右边的1变为0了。

重复操作,有多少个1,这个操作就可以执行多少次。

我这人比较小白 所以将上面的理解了一 用例子中的 4 9 15 举例
当n为4 时 二进制为 100 n-1 为 011

1 0 0
0 1 1
-----------只执行一次 代表只有一个1
0 0 0

当n为9 时 二进制为 1001 n-1 为 1000

1 0 0 1
1 0 0 0
-------------执行第一次 只有一个为1  其余都为0 在一次进行减一  现在 n 为1000  n-1为 0111
1 0 0 0
0 1 1 1 
-------------这一次不存在1了 所以执行结束 共执行两次 
0 0 0 0

当n为15 时 二进制为 1111 n-1 为 1110

1 1 1 1 
1 1 1 0
-----------执行第一次 后 n 为 1110  n-1为 1101
1 1 1 0
1 1 0 1
-----------执行第二次 后 n 为 1100 n-1 为 1011
1 1 0 0
1 0 1 1
-----------执行第三次 后 n 为 1000 n-1 为 0111
1 0 0 0
0 1 1 1
-----------第四次执行 这一次没有1 了 执行结束 共执行4次
0 0 0 0
本人只是为了记录自己的经历,如果侵犯到您的权益 ,请与1194821568@qq.com联系
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值