11_NumberOf1

题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示

package com.hwx.swordToOffer._11_NumberOf1;

/*
 * 题目描述
	输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示
 */


public class Solution {

	public static void main(String[] args) {

		System.out.println(NumberOf1_II(-2));
	}

	/*
	 * 最优解:
	 * 
		如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,
	那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。
	其余所有位将不会受到影响。
		举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,
	它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。
		这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。
	如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.
	那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。
	 */
	
	/*
	 负数的过程是一样的,只不过负数在计算机中是用反码的补码表示的,至于算1的个数那就是同样的过程。
	 */
	public static int NumberOf1(int n) {
		int count=0;
		while(n!=0) {
			n=n&(n-1);
			count++;
		}
		return  count;
	}
	
	/*不错的解法:
	 * 用1和n的每位进行位与,来判断1的个数
	 */
	public static int NumberOf1_II(int n) {
		int count=0;
		int flag=1;
		while(flag!=0) {
			if((flag & n)!=0) {//如果该位不为1,与的结果为0
				count++;
			}
			flag=flag<<1;//flag向左移动一位,一直循环直到移动32后变为0
		}
		return count;
	}
	/*
	 * 我的方法,使用了Integer.toBinaryString()方法,没有用到与运算,不好,要用自己的方法判断
	 */
	public static int NumberOf1_III(int n) {
		String binaryString = Integer.toBinaryString(n);
		int count=0;
		for(int i=0;i<binaryString.length();i++) {
			if(binaryString.charAt(i)=='1') {
				count++;
			}
		}
		return count;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
void eeprom_buffer_write(uint8_t* p_buffer, uint8_t write_address, uint16_t number_of_byte) { uint8_t number_of_page = 0, number_of_single = 0, address = 0, count = 0; address = write_address % I2C_PAGE_SIZE; count = I2C_PAGE_SIZE - address; number_of_page = number_of_byte / I2C_PAGE_SIZE; number_of_single = number_of_byte % I2C_PAGE_SIZE; //write_address相对于当前页的偏移量 //count表示该页中还剩余多少可写的空间 //number_of_page表示要写入的整个页数(即不包括最后一页) //number_of_single表示要写入的最后一页的字节数 if(0 == address){ while(number_of_page--){ eeprom_page_write(p_buffer, write_address, I2C_PAGE_SIZE); eeprom_wait_standby_state(); write_address += I2C_PAGE_SIZE; p_buffer += I2C_PAGE_SIZE; } if(0 != number_of_single){ eeprom_page_write(p_buffer, write_address, number_of_single); eeprom_wait_standby_state(); } }else{ /* if write_address is not I2C_PAGE_SIZE aligned / // if(number_of_byte < count){ eeprom_page_write(p_buffer, write_address, number_of_byte); eeprom_wait_standby_state(); }else{ number_of_byte -= count; number_of_page = number_of_byte / I2C_PAGE_SIZE; number_of_single = number_of_byte % I2C_PAGE_SIZE; if(0 != count){ eeprom_page_write(p_buffer, write_address, count); eeprom_wait_standby_state(); write_address += count; p_buffer += count; } / write page / while(number_of_page--){ eeprom_page_write(p_buffer, write_address, I2C_PAGE_SIZE); eeprom_wait_standby_state(); write_address += I2C_PAGE_SIZE; p_buffer += I2C_PAGE_SIZE; } / write single */ if(0 != number_of_single){ eeprom_page_write(p_buffer, write_address, number_of_single); eeprom_wait_standby_state(); } } } }详细解释这段的代码的每一个语句
最新发布
06-10
这段代码是用于在EEPROM中写入数据的函数。下面对每个语句进行详细解释: 1. uint8_t number_of_page = 0, number_of_single = 0, address = 0, count = 0; 定义4个变量,分别为要写入的整页数、最后一页的字节数、写入地址的偏移量和当前页可写入的字节数。 2. address = write_address % I2C_PAGE_SIZE; 求出写入地址相对于当前页的偏移量。 3. count = I2C_PAGE_SIZE - address; 计算当前页中还剩余多少可写的空间。 4. number_of_page = number_of_byte / I2C_PAGE_SIZE; 计算要写入的整个页数(即不包括最后一页)。 5. number_of_single = number_of_byte % I2C_PAGE_SIZE; 计算要写入的最后一页的字节数。 6. if(0 == address){ 如果写入地址已经对齐到一页的起始地址,执行以下的循环。 7. while(number_of_page--){ 循环写入整页数据。 8. eeprom_page_write(p_buffer, write_address, I2C_PAGE_SIZE); 写入一个整页的数据到EEPROM中。 9. eeprom_wait_standby_state(); 等待EEPROM进入就绪状态。 10. write_address += I2C_PAGE_SIZE; 将写入地址指向下一页的起始地址。 11. p_buffer += I2C_PAGE_SIZE; 将数据指针移动到下一页的起始地址。 12. if(0 != number_of_single){ 如果还有剩余的字节需要写入,执行以下代码。 13. eeprom_page_write(p_buffer, write_address, number_of_single); 写入最后一页的数据到EEPROM中。 14. eeprom_wait_standby_state(); 等待EEPROM进入就绪状态。 15. }else{ 如果没有剩余的字节需要写入,直接结束函数。 16. }else{ 如果写入地址没有对齐到一页的起始地址,执行以下代码。 17. if(number_of_byte < count){ 如果要写入的字节数小于当前页可写的字节数,执行以下代码。 18. eeprom_page_write(p_buffer, write_address, number_of_byte); 直接写入所有字节到当前页中。 19. eeprom_wait_standby_state(); 等待EEPROM进入就绪状态。 20. }else{ 如果要写入的字节数大于当前页可写的字节数,执行以下代码。 21. number_of_byte -= count; 将当前页可写的字节数从要写入的字节数中减去。 22. number_of_page = number_of_byte / I2C_PAGE_SIZE; 计算要写入的整个页数(即不包括最后一页)。 23. number_of_single = number_of_byte % I2C_PAGE_SIZE; 计算要写入的最后一页的字节数。 24. if(0 != count){ 如果当前页还有剩余的空间可写,执行以下代码。 25. eeprom_page_write(p_buffer, write_address, count); 将当前页剩余的空间全部写入。 26. eeprom_wait_standby_state(); 等待EEPROM进入就绪状态。 27. write_address += count; 将写入地址指向下一页的起始地址。 28. p_buffer += count; 将数据指针移动到下一页的起始地址。 29. } 30. while(number_of_page--){ 循环写入整页数据。 31. eeprom_page_write(p_buffer, write_address, I2C_PAGE_SIZE); 写入一个整页的数据到EEPROM中。 32. eeprom_wait_standby_state(); 等待EEPROM进入就绪状态。 33. write_address += I2C_PAGE_SIZE; 将写入地址指向下一页的起始地址。 34. p_buffer += I2C_PAGE_SIZE; 将数据指针移动到下一页的起始地址。 35. } 36. if(0 != number_of_single){ 如果还有剩余的字节需要写入,执行以下代码。 37. eeprom_page_write(p_buffer, write_address, number_of_single); 写入最后一页的数据到EEPROM中。 38. eeprom_wait_standby_state(); 等待EEPROM进入就绪状态。 39. } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值