您的位置:首页 > 职场人生

最近做的一些比较基础的笔试面试题目

2012-10-12 10:45 585 查看
最近也参加了一些笔试,也看了一些笔试的题目。感觉不管是一些普通的公司还是牛一些的,都会考一些基本的编程题和算法题。毕竟笔试的时间也就是那么1,2个小时。而其实这些基础的编程和算法题是需要考察一个人的基础扎实度的,这些题目的特点是,如果基础不扎实,思路没想到,这些题目也会话费很长时间而不得解,如果找到正确的方法,这些题目都会迎刃而解。所以说,这些题目看似简单,但是实则也是很有区分度的,也应该认真对待。

Amazon

1. 先给出一个原始的整数序列A,判断另外一个序列B是否可以通过A在栈的push和pop操作得到。例如:1,2,3,4,,然后再给出一个3,2,4,1。则B可以通过A push1 push2 push3 pop3 pop2 push4 pop4 pop1得到。使用程序输出push和pop操作顺序。

思路:关键在于比对序列A和序列B的对应关系,如果A中的数和B的不对应,则应该是push操作,使用一个临时堆栈s,保存push到s中的数,如果发现s的栈顶的数与B序列相等,则说明是pop出来的,则将s同样pop。然后继续循环操作比较B的下一个数。完整代码如下:

#include <iostream>
#include <stack>
//#define N 5

using namespace std;

/*
* 将a
的序列按照b
的序列输出的push、pop操作序列
*/
void Fun(int *a, int *b, int len){
stack<int> s;
int i=0,j=0;
while(j<len){
//比对临时堆栈堆顶与b
关系,如果为空或不等,需要将a
内容压入,是一个push操作,否则弹出临时堆栈,是一个pop操作。
if(s.empty() || s.top() != b[j]){
s.push(a[i]);
cout << "push "<<a[i]<<"| ";
++i;
}else{
s.pop();
cout << "pop "<<b[j]<<"| ";
++j;
}
}
cout <<endl;
//如果为空,则说明b
可以由堆栈a
根据push、pop序列得到
if(s.empty()) cout<<"正确的序列"<<endl;
else cout<<"错误的序列"<<endl;
}
int main(){
int i,N; //序列的数量
cin >> N;
while(N!=0){
int *a = new int
;
int *b = new int
;
cout << "输入初始序列:";
for(i=0;i<N;i++){
cin >> a[i];
}
cout << "输入变化后序列:";
for(i=0;i<N;i++){
cin >> b[i];
}

Fun(a,b,N);
cin >> N;
}
//system("pause");
return 0;
}


该题目即为微软100题的29题:/article/1360515.html

百度

2. 求一个字符串S的全排列结果:

思路:可以想到,使用递归可以实现全排列,例如对于123,可以输出1(23)的排列,2(13)的排列,3(12),即对一个序列,从start位置,一直遍历到end位置,每次遍历递归调用,直到start=end时,递归结束,输出该序列。

#include <stdlib.h>
#include <stdio.h>
#define N 4

void Swap(char *a, char *b){
char temp;
temp=*a;
*a=*b;
*b=temp;
}

void Arrange(char a[], int start, int end){
int i;
char temp;
if(start == end){
for(i = 0; i <= end; i++)
printf(" %c ",a[i]);
printf("\n");
}else{
for(i = start; i <= end; i++){
Swap(a+start,a+i);
Arrange(a, start+1, end);
Swap(a+start,a+i);
}
}
}

int main(){
printf("输入%d个字符:",N);
char *a=(char *)malloc(sizeof(char)*N);
for(int i=0;i<N;i++){
scanf("%c",a+i);
}
Arrange(a,0,N-1);
printf("\n");
system("pause");
return 0;
}
这篇博客给了很多种该问题的不同变种:http://blog.csdn.net/zz198808/article/details/7657168

百度-面试题

3. 怎么手工计算从1到1亿的出现的所有数的和。

做这道题,我受了编程之美里面有一道找1的数量拿到题目的影响,上来就找数字出现的规律,虽然也找到了一些规律,但是计算还是很麻烦。事实上,我们想一下,我们计算一个顺序出现的数从1到N怎么算,使用高斯定理(1+N)*N/2,而高斯定理的思想就是顺序数列1+N=2+(N-1)=3+(N-2)=...即前后两两配对的。所以同样可以采用这种策略计算出现的数字的和。

可以这样分组:(0,99999999),(1,99999998),(2,99999997)(3,99999996)……(49999999,50000000),共50000000组,还剩下数字100000000。

这样每一组的数字之和都是:9*8=72

总和为:72*50000000+1=3600000001(36亿零1)

或者使用加法的竖列来观察。



0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 1

……………………



9 9 9 9 9 9 9 9

得到一个8列、1亿行的数组

看其中任何一列:0-9都出现1千万次

解法如下:(0+1+2+3+4+5+6+7+8+9)*1千万*8列+1(1亿的)=45*8*1千万+1=36亿零1

参考的博客为:/article/3908329.html

百度-笔试

4. 一个数字串N,f(N)是位数和N一样,各位总和也和N一样,但是数值上大于N的最小数

例如N = 020,那么f(N) = 101,如果不存在f(N),则f(N)
= -1
思想是:
先计算数字串N的总和sum,然后需要判断数字串中第一个非0数字的位置pos和第一个非0数字a[pos]与总和sum的关系,分以下几种情况:
1) 如果N=1,则返回-1,不能找到该数
2) 当数串为全0时,返回-1
3) 当第一个非0数与sum相等时,如果pos=0,则返回-1,因为如果在第一位比a[pos]大,则总和超出sum了。否则,a[pos-1]=1
4) 当第一个非0数与sum不相等时,则第一个数为a[pos]+1.
将第一位确定之后,剩下的差值放在最后。

#include <stdlib.h>
#include <stdio.h>
#define N 5

//将剩余的几个数放在数组b中的最末尾
void AddLeft(int b[], int num, int len){
for(int i = len-1; num!=0 ; num/=10,--i){
b[i]=num%10;
}
}
int Fun(int a[], int b[], int len){
int flag=0;
int maxpos=-1; //第一个非0数的位置
int sum=0;     //数串总和
if(len == 1) return -1;  //只有一位,则不可能找到
for(int i=0;i<N;i++){
if(a[i] != 0 && flag==0){
maxpos=i;
flag=1;
}
sum+=a[i];
}
if(maxpos == -1) return -1; //为全0,则不可能找到
if(sum == a[maxpos]){
if(maxpos == 0) return -1;  //如果非0为第一位,则不能得到
else{
b[maxpos-1]=1;     //否则可以在大一位上设置为1
AddLeft(b, sum-1,N);
return 1;
}
}else{
//当总和比第一个非0数要大时,可以在非0数的数位加1
b[maxpos]=a[maxpos]+1;
AddLeft(b, sum-b[maxpos],N);
return 1;
}
}

int main(){
int a
,b
={0};
printf("输入%d个数:",N);
for(int i=0;i<N;i++){
scanf("%d",a+i);
}
if(Fun(a,b,N)!=-1){
printf("可以转化为:");
for(int i=0;i<N;i++){
printf("%d ",b[i]);
}
}else{
printf("不能转化!");
}
printf("\n");
system("pause");
return 0;
}


5. 腾讯笔试:把两个数和告诉A,积告诉B,求这两个数是什么
1-20的两个数把和告诉A,积告诉B,
A说不知道是多少,
B也说不知道,
这时A说我知道了,
B接着说我也知道了,

问这两个数是多少?

挺有意思的一道题:看似无从下手,其实主要解决点在这里:B说不知道之后,A即知道。则说明A中和的几种情况中,应该仅有一种导致乘积不能确定两个数是多少。应该从乘积最小的开始算起来。
如果两个数可以重复:
B=4时,可能是1*4或2*2,A=4,4=1+3,4=2+2。1,3两个数B可以确定为3,所以一定为2,2。
B=6时,可能是1*6或2*3。那么当A=5时,5=1+4,5=2+3,如果5=1+4,则B不能确定,只剩下2,3这种情况,所以两个数可以为2,3。

如果两个数不能重复,
A=5=2+3=1+4,如果是1,4,B=4=1*4,应该说知道,所以不是1,4,只能是2,3。这时B=6,6=1*6=2*3,A说知道了,如果是1,6的话,A=7=1+6=2+5=3+4,不满足。所以只能是2,3情况,A=5=1+4=2+3。A不能是1,4。所以最后确定两个数是2,3.
A=6=2+4=1+5,如果是1,5,B=5=1*5,应该说知道,所以不是1,5,只能是2,4。这时B=8,8=1*8=2*4,只能是2,4满足。
所以不论是可重复还是不能重复,一定有2,3,这种情况

百度-笔试
6. 编写函数,统计在某段英文文本中完整句子的数目,文本中只包括大小写字母,空格,点好(.),逗号(,)。

完整的句子必须包含至少一个字母并以点号,结束。

要求:完整的代码,达到目标;高效;简洁;

#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp;
char ch;
char *dir="data.txt";
if((fp=fopen(dir,"rt"))==NULL){
printf("Cannot open file strike any key exit!");
return -1;
}

int num=0; //句子数量
int charNum=0;
while((ch=getc(fp))!=EOF){
printf("%c",ch);
if(ch!='.'){
if( (ch >='a'&& ch <='z') || (ch >='A'&& ch <='Z') ) charNum++;
else charNum=0;
}else if(charNum != 0){
num++;
charNum=0;
}
}
printf("\n句子数量是:%d\n",num);
fclose(fp);
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: