PowerWind

网络管理和高校信息化

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

名企笔试之华为的笔试题二

Posted on 2011-06-25 12:56  PowerWind  阅读(495)  评论(0)    收藏  举报

上面是基本问题,接下来是编程问题:


本人很弱,这几个题也搞不定,特来求救:
1)读文件file1.txt的内容(例如):
12
34
56
输出到file2.txt:
56
34
12
(逆序)
2)输出和为一个给定整数的所有组合
例如n=5
5=1+4;5=2+3(相加的数不能重复)
则输出
1,4;2,3。
望高手赐教!!

第一题,注意可增长数组的应用.
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
         int MAX = 10;
int *a = (int *)malloc(MAX * sizeof(int));
int *b;
   
FILE *fp1;
FILE *fp2;

fp1 = fopen("a.txt","r");
if(fp1 == NULL)
{printf("error1");
    exit(-1);
}

    fp2 = fopen("b.txt","w");
if(fp2 == NULL)
{printf("error2");
    exit(-1);
}

int i = 0;
    int j = 0;

while(fscanf(fp1,"%d",&a[i]) != EOF)
{
i++;
j++;
if(i >= MAX)
{
MAX = 2 * MAX;
b = (int*)realloc(a,MAX * sizeof(int));
if(b == NULL)
{
printf("error3");
exit(-1);
}
a = b;
}
}

for(;--j >= 0;)
   fprintf(fp2,"%d\n",a[j]);

fclose(fp1);
fclose(fp2);

return 0;


}

第二题.
#include <stdio.h>

int main(void)
{
unsigned long int i,j,k;

printf("please input the number\n");
scanf("%d",&i);
    if( i % 2 == 0)
        j = i / 2;
else
j = i / 2 + 1;

printf("The result is \n");
    for(k = 0; k < j; k++)
     printf("%d = %d + %d\n",i,k,i - k);
return 0;
}

#include <stdio.h>
void main()
{
unsigned long int a,i=1;
scanf("%d",&a);
if(a%2==0)
{
     for(i=1;i<a/2;i++)
     printf("%d",a,a-i);
}
else
for(i=1;i<=a/2;i++)
        printf(" %d, %d",i,a-i);
}

兄弟,这样的题目若是做不出来实在是有些不应该, 给你一个递规反向输出字符串的例子,可谓是反序的经典例程.

void inverse(char *p)
{
    if( *p = = '\0' )
return;
    inverse( p+1 );
    printf( "%c", *p );
}

int main(int argc, char *argv[])
{
    inverse("abc\0");

    return 0;
}

借签了楼上的“递规反向输出”
#include <stdio.h>
void test(FILE *fread, FILE *fwrite)
{
        char buf[1024] = {0};
        if (!fgets(buf, sizeof(buf), fread))
                return;
        test( fread, fwrite );
        fputs(buf, fwrite);
}
int main(int argc, char *argv[])
{
        FILE *fr = NULL;
        FILE *fw = NULL;
        fr = fopen("data", "rb");
        fw = fopen("dataout", "wb");
        test(fr, fw);
        fclose(fr);
        fclose(fw);
        return 0;
}

在对齐为4的情况下
struct BBB
{
   long num;
   char *name;
   short int data;
   char ha;
   short ba[5];
}*p;
p=0x1000000;
p+0x200=____;
(Ulong)p+0x200=____;
(char*)p+0x200=____;
希望各位达人给出答案和原因,谢谢拉
解答:假设在32位CPU上,
sizeof(long) = 4 bytes
sizeof(char *) = 4 bytes
sizeof(short int) = sizeof(short) = 2 bytes
sizeof(char) = 1 bytes

由于是4字节对齐,
sizeof(struct BBB) = sizeof(*p)
= 4 + 4 + 2 + 1 + 1/*补齐*/ + 2*5 + 2/*补齐*/ = 24 bytes (经Dev-C++验证)

p=0x1000000;
p+0x200=____;
    = 0x1000000 + 0x200*24

(Ulong)p+0x200=____;
    = 0x1000000 + 0x200

(char*)p+0x200=____;
    = 0x1000000 + 0x200*4

写一段程序,找出数组中第k大小的数,输出数所在的位置。例如{2,4,3,4,7}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。函数接口为:int find_orderk(const int* narry,const int n,const int k)
要求算法复杂度不能是O(n^2)
谢谢!
可以先用快速排序进行排序,其中用另外一个进行地址查找
代码如下,在VC++6.0运行通过。给分吧^-^

//快速排序

#include<iostream>

usingnamespacestd;

intPartition (int*L,intlow,int high)
{
inttemp = L[low];
intpt = L[low];

while (low < high)
{
while (low < high && L[high] >= pt)
--high;
L[low] = L[high];
while (low < high && L[low] <= pt)
++low;
L[low] = temp;
}
L[low] = temp;

returnlow;
}

voidQSort (int*L,intlow,int high)
{
if (low < high)
{
intpl = Partition (L,low,high);

QSort (L,low,pl - 1);
QSort (L,pl + 1,high);
}
}

intmain ()
{
intnarry[100],addr[100];
intsum = 1,t;

cout << "Input number:" << endl;
cin >> t;

while (t != -1)
{
narry[sum] = t;
addr[sum - 1] = t;
sum++;

cin >> t;
}

sum -= 1;
QSort (narry,1,sum);

for (int i = 1; i <= sum;i++)
cout << narry[i] << '\t';
cout << endl;

intk;
cout << "Please input place you want:" << endl;
cin >> k;

intaa = 1;
intkk = 0;
for (;;)
{
if (aa == k)
break;
if (narry[kk] != narry[kk + 1])
{
aa += 1;
kk++;
}

}

cout << "The NO." << k << "number is:" << narry[sum - kk] << endl;
cout << "And it's place is:" ;
for (i = 0;i < sum;i++)
{
if (addr[i] == narry[sum - kk])
cout << i << '\t';
}


return0;
}

1、找错
Void test1()
{
char string[10];
char* str1="0123456789";
strcpy(string, str1);// 溢出,应该包括一个存放'\0'的字符string[11]
}


Void test2()
{
char string[10], str1[10];
for(I=0; I<10;I++)
{
str1[i] ='a';
}
strcpy(string, str1);// I,i没有声明。
}

Void test3(char* str1)
{
char string[10];
if(strlen(str1)<=10)// 改成<10,字符溢出,将strlen改为sizeof也可以
{
strcpy(string, str1);
}
}

2.
void g(int**);
int main()
{
int line[10],i;
int *p=line; //p是地址的地址
for (i=0;i<10;i++)
{
*p=i;
g(&p);//数组对应的值加1
}
for(i=0;i<10;i++)
printf("%d\n",line[i]);
return 0;
}

void g(int**p)
{
(**p)++;
(*p)++;// 无效
}
输出:
1
2
3
4
5
6
7
8
9
10
3. 写出程序运行结果

int sum(int a)
{
auto int c=0;
static int b=3;
c+=1;
b+=2;
return(a+b+c);
}

void main()
{
int I;
int a=2;
for(I=0;I<5;I++)
{
printf("%d,", sum(a));
}
}
// static会保存上次结果,记住这一点,剩下的自己写
输出:8,10,12,14,16,


4.

int func(int a)
{
int b;
switch(a)
{
case 1: 30;
case 2: 20;
case 3: 16;
default: 0
}
return b;
}
则func(1)=?
// b定义后就没有赋值。

5:
int a[3];
a[0]=0; a[1]=1; a[2]=2;
int *p, *q;
p=a;
q=&a[2];
则a[q-p]=a[2]
解释:指针一次移动一个int但计数为1

今天早上的面试题9道,比较难,向牛人请教,国内的一牛公司,坐落在北京北四环某大厦:
1、线形表a、b为两个有序升序的线形表,编写一程序,使两个有序线形表合并成一个有序升序线形表h;
答案在 请化大学 严锐敏《数据结构第二版》第二章例题,数据结构当中,这个叫做:两路归并排序
Linklist *unio(Linklist *p,Linklist *q){
linklist *R,*pa,*qa,*ra;
pa=p;
qa=q;
R=ra=p;
while(pa->next!=NULL&&qa->next!=NULL){
if(pa->data>qa->data){
ra->next=qa;
qa=qa->next;
}
else{
ra->next=pa;
pa=pa->next;
}
}
if(pa->next!=NULL)
ra->next=pa;
if(qa->next!=NULL)
ra->next==qa;
return R;
}
2、运用四色定理,为N个局域举行配色,颜色为1、2、3、4四种,另有数组adj[][N],如adj[i][j]=1则表示i区域与j区域相邻,数组color[N],如color[i]=1,表示i区域的颜色为1号颜色。
四色填充
3、用递归算法判断数组a[N]是否为一个递增数组。
递归的方法,记录当前最大的,并且判断当前的是否比这个还大,大则继续,否则返回false结束:
bool fun( int a[], int n )
{
if( n= =1 )
return true;
if( n= =2 )
return a[n-1] >= a[n-2];
return fun( a,n-1) && ( a[n-1] >= a[n-2] );
}
4、编写算法,从10亿个浮点数当中,选出其中最大的10000个。
用外部排序,在《数据结构》书上有
《计算方法导论》在找到第n大的数的算法上加工
5、编写一unix程序,防止僵尸进程的出现.
*********************************************************************
同学的4道面试题,应聘的职位是搜索引擎工程师,后两道超级难,(希望大家多给一些算发)
1.给两个数组和他们的大小,还有一动态开辟的内存,求交集,把交集放到动态内存dongtai,并且返回交集个数
long jiaoji(long* a[],long b[],long* alength,long blength,long* dongtai[])
2.单连表的建立,把'a'--'z'26个字母插入到连表中,并且倒叙,还要打印!
方法1:
typedef struct val
{   int date_1;
    struct val *next;
}*p;

void main(void)
{   char c;
    
    for(c=122;c>=97;c--)
       { p.date=c;
         p=p->next;
        }

    p.next=NULL;
}
}
方法2:
node *p = NULL;
node *q = NULL;

node *head = (node*)malloc(sizeof(node));
head->data = ' ';head->next=NULL;

node *first = (node*)malloc(sizeof(node));
first->data = 'a';first->next=NULL;head->next = first;
p = first;

int longth = 'z' - 'b';
int i=0;
while ( i<=longth )
{
node *temp = (node*)malloc(sizeof(node));
temp->data = 'b'+i;temp->next=NULL;q=temp;

head->next = temp; temp->next=p;p=q;
i++;
}

print(head);
1.这样的初始化有什么问题?char *p = malloc(10); 编译器提示“非法初始式” 云云。

答:这个声明是静态或非局部变量吗?函数调用只能出现在自动变量(即局部非静态变量) 的初始式中。
因为静态变量的地址必须在编译的过程中就确定下来而malloc()申请的内存地址是在运行时确定的。

2. *p++ 自增p 还是p 所指向的变量?

答:后缀++ 和-- 操作符本质上比前缀一目操作的优先级高, 因此*p++ 和*(p++) 等价, 它自增p 并返回p 自增之前所指向的值。
要自增p 指向的值, 使用(*p)++, 如果副作用的顺序无关紧要也可以使用++*p。

3 我有一个char * 型指针正巧指向一些int 型变量, 我想跳过它们。为什么如下的代码((int *)p)++; 不行?

答:在C 语言中, 类型转换意味着“把这些二进制位看作另一种类型, 并作相应的对待”; 这是一个转换操作符,
根据定义它只能生成一个右值(rvalue)。而右值既不能赋值, 也不能用++ 自增。(如果编译器支持这样的扩展,
那要么是一个错误, 要么是有意作出的非标准扩展。) 要达到你的目的可以用:p = (char *)((int *)p + 1);
或者,因为p 是char * 型, 直接用p += sizeof(int);

4.空指针和未初始化的指针是一回事吗?

答:空指针在概念上不同于未初始化的指针:空指针可以确保不指向任何对象或函数;
而未初始化指针则可能指向任何地方。

5.我可以用0来表示空指针吗?

答:根据语言定义, 在指针上下文中的常数0 会在编译时转换为空指针。也就是说, 在初始化、赋值或比较的时候,
如果一边是指针类型的值或表达式, 编译器可以确定另一边的常数0 为空指针并生成正确的空指针值。因此下边的代码段完全合法:
char *p = 0;
if(p != 0)

然而, 传入函数的参数不一定被当作指针环境, 因而编译器可能不能识别未加修饰的0 “表示” 指针。
在函数调用的上下文中生成空指针需要明确的类型转换,强制把0 看作指针。
例如, Unix 系统调用execl 接受变长的以空指针结束的字符指针参数。它应该如下正确调用:
execl("/bin/sh", "sh", "-c", "date", (char *)0);
如果省略最后一个参数的(char *) 转换, 则编译器无从知道这是一个空指针,从而当作一个0 传入。(注意很多Unix 手册在这个例子上都弄错了。)


摘要:
==========================|=============================
||   可以使用未加修饰的0   | 需要显示的类型转换         ||
||------------------------|---------------------------||
||   *初始化              | *函数调用, 作用域内无原型 ||
||   *赋值                | *变参函数调用中的可变参数 ||
||   *比较                |                           ||
||   *固定参数的函数调用   |                           ||
||    且在作用域内有原型   |                           ||
==========================|=============================

有两条简单规则你必须遵循:
1) 当你在源码中需要空指针常数时, 用“0” 或“NULL”。
2) 如果在函数调用中“0” 或“NULL” 用作参数, 把它转换成被调函数需要的指针类型