在Excel2003中,用A表示第1列,B表示第2列......Z表示第26列,AA表示第27列,AB表示第28列......以此类推。请写出一个函数,输入用字母表示的列号编码,输出它是第几列。
分析:其实这道题就是十进制和26进制之间的转化;
A = 26^0 + 1 = 1
AA = 26 * (26^0 + 1) + 1 = 26 * A + 1
AAA = 26 * [26 * (26^0 + 1)+1] + 1 = 26 * AA + 1
AB = 2*26^0 + 1*26^1 = 26 * A + 2
ABC = 3 * 26^0 + 2 * 26^1 + 1 * 26^2
#include<stdio.h>
#include<string.h>
int Change()
{
char ch[200];
scanf("%s",ch);
int size = strlen(ch);
int i = 0;
int ret = 0;
for(;i<size;i++)
{
int tmp = ch[i]-'A';
if(tmp<0 || tmp >=26)//无效输入
{
printf("invalid input\n");
return -1;
}
ret = 26*ret + tmp+1;
}
return ret;
}
int main()
{
while(1)
{
int ret = Change();
printf("ch:%d\n",ret);
}
return 0;
}
题目:计算一个二进制数中1的个数
方法一:利用模2除2(负数出现死循环)
while (a)
{
if (a % 2 == 1)
{
count++;
}
a /= 2;
}
方法二:最右边比特位按位&1 == 1
for (i = 1; i <= 32; i++)
{
if ((a & 1) == 1)
{
count++;
}
a = a >> 1;
}
方法三:
分析:
while (a)
{
a = a&(a - 1);
count++;
}
printf("count = %d\n", count);
题目:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。(领扣:https://leetcode-cn.com/problems/single-number-ii/description/)
int singleNumber(int* nums, int numsSize) {
int i = 0;
int ret = 0;
for(;i<32;i++)
{
int sum = 0;
int j = 0;
for(;j<numsSize;j++)
{
sum += (nums[j]>>i) & 1;
}
ret |= (sum % 3)<<i;
}
return ret;
}
大神解法
int singleNumber(int* nums, int numsSize) {
int a = 0, b = 0,i=0;
for(int i = 0;i < numsSize;i++)
{
b = (b ^ nums[i]) & ~a;
a = (a ^ nums[i]) & ~b;
}
return b;
}
题目:给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
说明:
- 不能更改原数组(假设数组是只读的)。
- 只能使用额外的 O(1) 的空间。
- 时间复杂度小于 O(n2) 。
- 数组中只有一个重复的数字,但它可能不止重复出现一次。
当不考虑条件4的时候:下面代码成立
分析:数组有n+1个元素,题目说明数组包含1和n,所以在这个数组中包含了1到n所以的数字,只是多了一个重复的数字。我们可以利用异或解决此题
1^2^3^3^4^5 ^ (1^2^3^4^5) = 3;最终只有3异或了三次,而其他数异或了两次,所以最终结果为3
int findDuplicate(int* nums, int numsSize) {
int ret = 0;
int i = 0;
for (; i < numsSize; i++){
ret ^= nums[i];
ret ^= i;
}
return ret;
}
当考虑第四个条件:参考我的上一篇博客:https://blog.youkuaiyun.com/weixin_41318405/article/details/79682281
题目:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。(领扣:https://leetcode-cn.com/problems/single-number/description/)
分析:采用异或算法;两个相同的数异或结果等于0,任何数与0异或等于他本身,异或是半加运算,具有交换律
int singleNumber(int* nums, int numsSize) {
int ret = 0;
int i = 0;
for(;i<numsSize;i++)
{
ret = ret^nums[i];
}
return ret;
}
题目:给定一个整数数组
nums
,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
分析:首先所以数字异或得到一个混合结构ret,然后找ret二进制第一次出现1的位置(这个位置代表,是两个不同的数异或得到的结果)所以,利用此位置为1,吧数组分成两部分,一部分是在该位置为0,另外一部分是在该位置为1,当然这两个数肯定会出现在不同的部分,然后利用上题思想,求得两个数
int* singleNumber(int* nums, int numsSize) {
int arr[2] = { 0 };
int ret = 0;
int i = 0;
for (; i<numsSize; i++)
{
ret ^= nums[i];
}
for (i = 0; i<32; i++)
{
if (((ret >> i) & 1) == 1)
break;
}
int j = 0;
for (; j<numsSize; j++)
{
if ((nums[j] >> i) &1== 1)
arr[0] ^= nums[j];
else
arr[1] ^= nums[j];
}
return arr;
}
题目:给定两个字符串 s 和 t,它们只包含小写字母。
字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。
请找出在 t 中被添加的字母。
char findTheDifference(char* s, char* t) {
char ret = 0;
for(;*s != '\0';s++)
ret ^= *s;
for(;*t != '\0';t++)
ret ^= *t;
return ret;
}
相关题目:
(1)N+1块相同容量的硬盘,其中N块用来存储数据,剩余1块来存储N块硬盘的数据备份,假设同一时间最多一块硬盘有故障,那么该怎么存储数据
答案:异或存储,当其中一块坏了,直接用异或其他好的,结果就是有故障的哪一个
(2)用一条语句判断一个整数是不是2的整数次方
分析:一个整数如果是2的整数次方,那么该整数的二进制只有一个1比特位为1,所以我们可以让这个整数按位与该整数减1的结果,最终结果如果为0,那么就是2的整数次方(和上述题中找二进制中1的个数方法三一样的思想)
(3)输入两个整数m和n,计算需要改变m的二进制比特位多少位,才能得到n
分析:1. 两个数异或。 2. 找异或后结果1出现的次数
(4)把一个整数减1之后在和原来的整数按位与运算,得到的结果相当于吧该整数最右边的二进制数为1的位置改为0.