用位运算的一些面试题

背景:网上有太多的垃圾代码,所以一直不敢在写东西去垃圾别人;但是迫于形势开始写博客,不然简历没法写!!!

目标:希望通过自己的努力成为基础好、底子厚的一名合格的CS毕业生;

态度:摒弃浮躁、坚持多方位看问题;

观点:用最合适的方法去解决问题;

吐槽:虽然做一些变态的没有意义的题并不能解决实际的问题,但是确实是这个社会的需求,没有办法唯有遵守规则,才能变的和主流人群一样!!!

最近在看面试题,见过一些面试题都是可用位运算来解答,这个最原始的运算结构拥有强大的威力;

例1:

问题:找出字符串第一个出现且出现一次的字符;

输入:abdadbdcef

输出:c

思考方式

1-一看到字符串就联想到位储存和位运算;

2-用一个int 32位存储26字母,每个字母用一个位存储;假设变量为 int i=0;

位运算套路:(所有的方法都是有套路的)

1-首先,把输入字符串遍历一遍,在相应位置为1;

2-利用变量 i 中的位为1,做你想做的东西;

但是在这个题中却不能用这个套路原因是:

题目要求是:第一次 && 自有一个 出现的。所以多次出现要被干掉,标记1不起作用了(即使取反清零,奇数个才可以)

所以要转变思路,用一个数组来记录着一串字符,因为数组可以累积计数;

步骤:

1-建立数组 char store[] 存储字符串的位置;

2-假定都是小写字母,即:a-z ,把转变为下标0-25,下标=s[i] - 'a';

3-把字符串遍历一遍,如果是只出现一次,store[i] 必定是为1;

4-在按字符串的顺序遍历一遍,如果store[i]为1就是符合题意的;

代码如下:

#if 1
#include<stdio.h>
#include<string.h>

int main()
{
char s[] = "hehHenimei";
char store[58]={0}; //存储字符串中字符出现的次数,ASCII A-z : 65 - 122
int i =0;
   while(s[i] != '\0') //遍历字符串,建立字符出现的次数
   {
        store[s[i] - 'A'] ++;
        i++;
   }
    int len = strlen(s); //计算字符串的长度,代码外提,优化效率
    for( i = 0 ; i < len ; i++)
    if ( store[s[i] - 'A'] == 1 ) //等于1  你懂的 套路
    {
        printf("%c\n",s[i]);
        return 0;
    }

   return 1;
}
#endif

结果:
H

Process returned 0 (0x0)   execution time : 0.017 s
Press any key to continue.



例题2

<<span style="font-size:18px;">span style="font-size:18px;">题目要求:
1-字符串 A , B ;
2- strlen(A) > strlen(B) ; 
3-用神马方法查询B串中的字符在A中都有;
例如:
A : watenisgoodguy
B : waten
输出:TRUE
A : watenisgoodguy
B : nima
输出:FALSE 因为A中没有m

方法:一涉及到字符问题,第一反应位储存和运算;按套路来;
1-设计一个int i保存位,遍历A,把A串的字符所对应的位置为1;
2-遍历B,把B串的字符和i 相与大于零则表示A中有,否者没有报错</span>!
<span style="font-size:18px;">代码:
#include<stdio.h>

int main()
{
int i = 0 , index = 0 ;
char A[] = "watenisgoodguy";
char B[] = "waten";
while(A[index] != '\0')
{
	i |= 1<<(A[index] - 'a') ; //把相应的位置1
	index++;
}
index = 0 ;
while(B[index] != '\0' )
{
	if( (i& (1<<(B[index] - 'a') ) ) == 0 ) //相与 结果很明显 等与零 就说明B 在A 中没有!
		{
			printf("FALSE! \n");
		 	return 1;
		}
	index++;
}
printf(" TURE \n");
return 0;
}

</span></span>
 TURE

Process returned 0 (0x0)   execution time : 0.030 s
Press any key to continue.


但是这个是不符合题目要求的,因为没有考虑到大写字母,所以要用数组才储存,而不是一个整型变量;
修改代码如下:

<span style="font-size:18px;"><span style="font-size:18px;">#include<stdio.h>

int main()
{
	int i = 0 , index = 0 ,temp = 0 , t = 0; //index 下标

char A[] = "AwatenisgoodkguyH";
char B[] = "watenO";
char store[58] ={0};
while(A[index] != '\0')
{
    temp = (A[index] - 'A');
	store[temp]=1 ;
	index++;
}
index = 0 ;
while(B[index] != '\0' )
{
    t = (B[index] - 'A');
	if( store[t] != 1 ) //当不等于1的时候就就报错退出!!
		{
			printf("FALSE \n");
		 	return 1;
		}
	index++;
}
printf(" TURE \n");
return 0;
}</span></span>
FALSE

Process returned 1 (0x1)   execution time : 0.018 s
Press any key to continue.

当然也是可以用位运算的,不过比较麻烦,建立一个int store[2] 的64bits 存储ASCII 码 ‘A-z’

代码如下:

#if 1
#include<stdio.h>

int main()
{
	int i = 0 , index = 0 ,temp = 0 , t = 0; //index 下标

char A[] = "AwatenisgoodkguyH";
char B[] = "watenT";
int store[2] ={0};
while(A[index] != '\0')
{
    temp = (A[index] - 'A');
	store[temp/32] |= 1<<(temp%32-1) ; // temp /32 求数组的下标,本例是 0 1 ;  temp %32 -1 求置位的位置0-31 32-63
	index++;
}
index = 0 ;
while(B[index] != '\0' )
{
    t = (B[index] - 'A');
	if( !(store[t/32]& (1<<(t%32-1))) ) //如果位不为1 就输出错误!
		{
			printf("FALSE \n");
		 	return 1;
		}
	index++;
}
printf(" TURE \n");
return 0;
}
#endif



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值