Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4519511
  • 博文数量: 356
  • 博客积分: 10458
  • 博客等级: 上将
  • 技术积分: 4734
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-24 14:59
文章分类

全部博文(356)

文章存档

2020年(17)

2019年(9)

2018年(26)

2017年(5)

2016年(11)

2015年(20)

2014年(2)

2013年(17)

2012年(15)

2011年(4)

2010年(7)

2009年(14)

2008年(209)

分类: C/C++

2008-04-20 14:58:37

3.可怕的题目终于来了
            象搜索的输入信息是一个字符串,统计300万输入信息中的最热门的前十条,我们每次输
            入的一个字符串为不超过255byte,内存使用只有1G,
            请描述思想,写出算发(c语言),空间和时间复杂度,
            4.国内的一些帖吧,如baidu,有几十万个主题,假设每一个主题都有上亿的跟帖子,怎
            么样设计这个系统速度最好,请描述思想,写出算发(c语言),空间和时间复杂度,
            #include string.h
            main(void)
            { char *src="hello,world";
            char *dest=NULL;
            dest=(char *)malloc(strlen(src));
            int len=strlen(str);
            char *d=dest;
            char *s=src[len];
            while(len--!=0)
            d++=s--;
            printf("%s",dest);
            }
            找出错误!!
            #include "string.h"
            #include "stdio.h"
            #include "malloc.h"
            main(void)
            {
            char *src="hello,world";
            char *dest=NULL;
            dest=(char *)malloc(sizeof(char)*(strlen(src)+1));
            int len=strlen(src);
            char *d=dest;
            char *s=src+len-1;
            while(len--!=0)
            *d++=*s--;
            *d='\0';
            printf("%s",dest);
            }
            1. 简述一个Linux驱动程序的主要流程与功能。
            2. 请列举一个软件中时间换空间或者空间换时间的例子。
            void swap(int a,int b)
            {
            int c; c=a;a=b;b=a;
            }
            --->空优
            void swap(int a,int b)
            {
            a=a+b;b=a-b;a=a-b;
            }
            6. 请问一下程序将输出什么结果?
            char *RetMenory(void)
            {
            char p[] = “hellow world”;
            return p;
            }
            void Test(void)
            {
            char *str = NULL;
            str = RetMemory();
            printf(str);
            }
            RetMenory执行完毕,p资源被回收,指向未知地址。返回地址,str的内容应是不可预测
            的, 打印的应该是str的地址
            写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)
            功能:
            在字符串中找出连续最长的数字串,并把这个串的长度返回,并把这个最长数字串付给
            其中一个函数参数outputstr所指内存。例如:"abcd12345ed125ss123456789"的首地址
            传给intputstr后,函数将返回
            9,outputstr所指的值为123456789
            int continumax(char *outputstr, char *inputstr)
            {
            char *in = inputstr, *out = outputstr, *temp, *final;
            int count = 0, maxlen = 0;
            while( *in != '\0' )
            {
            if( *in > 47 && *in < 58 )
            {
            for(temp = in; *in > 47 && *in < 58 ; in++ )
            count++;
            }
            else
            in++;
            if( maxlen < count )
            {
            maxlen = count;
            count = 0;
            final = temp;
            }
            }
            for(int i = 0; i < maxlen; i++)
            {
            *out = *final;
            out++;
            final++;
            }
            *out = '\0';
            return maxlen;
            }
            不用库函数,用C语言实现将一整型数字转化为字符串
            方法1:
            int getlen(char *s){
            int n;
            for(n = 0; *s != '\0'; s++)
            n++;
            return n;
            }
            void reverse(char s[])
            {
            int c,i,j;
            for(i = 0,j = getlen(s) - 1; i < j; i++,j--){
            c = s[i];
            s[i] = s[j];
            s[j] = c;
            }
            }
            void itoa(int n,char s[])
            {
            int i,sign;
            if((sign = n) < 0)
            n = -n;
            i = 0;
            do{/*以反序生成数字*/
            s[i++] = n%10 + '0';/*get next number*/
            }while((n /= 10) > 0);/*delete the number*/
            if(sign < 0)
            s[i++] = '-';
            s[i] = '\0';
            reverse(s);
            }
            方法2:
            #include 
            using namespace std;
            void itochar(int num);
            void itochar(int num)
            {
            int i = 0;
            int j ;
            char stra[10];
            char strb[10];
            while ( num )
            {
            stra[i++]=num%10+48;
            num=num/10;
            }
            stra[i] = '\0';
            for( j=0; j < i; j++)
            {
            strb[j] = stra[i-j-1];
            }
            strb[j] = '\0';
            cout<
            }
            int main()
            {
            int num;
            cin>>num;
            itochar(num);
            return 0;
            }
            前几天面试,有一题想不明白,请教大家!
            typedef struct
            {
            int a:2;
            int b:2;
            int c:1;
            }test;
            test t;
            t.a = 1;
            t.b = 3;
            t.c = 1;
            printf("%d",t.a);
            printf("%d",t.b);
            printf("%d",t.c);
            谢谢!
            t.a为01,输出就是1
            t.b为11,输出就是-1
            t.c为1,输出也是-1
            3个都是有符号数int嘛。
            这是位扩展问题
            01
            11
            1
            编译器进行符号扩展
            求组合数: 求n个数(1....n)中k个数的组合....
            如:combination(5,3)
            要求输出:543,542,541,532,531,521,432,431,421,321,
            #include
            int pop(int *);
            int push(int );
            void combination(int ,int );
            int stack[3]={0};
            top=-1;
            int main()
            {
            int n,m;
            printf("Input two numbers:\n");
            while( (2!=scanf("%d%*c%d",&n,&m)) )
            {
            fflush(stdin);
            printf("Input error! Again:\n");
            }
            combination(n,m);
            printf("\n");
            }
            void combination(int m,int n)
            {
            int temp=m;
            push(temp);
            while(1)
            {
            if(1==temp)
            {
            if(pop(&temp)&&stack[0]==n) //当栈底元素弹出&&为可能取的最小值,循环退出
            break;
            }
            else if( push(--temp))
            {
            printf("%d%d%d ",stack[0],stack[1],stack[2]);//§ä¨ì¤@?
            pop(&temp);
            }
            }
            }
            int push(int i)
            {
            stack[++top]=i;
            if(top<2)
            return 0;
            else
            return 1;
            }
            int pop(int *i)
            {
            *i=stack[top--];
            if(top>=0)
            return 0;
            else
            return 1;
            }
            1、用指针的方法,将字符串“ABCD1234efgh”前后对调显示
            #include 
            #include 
            #include 
            int main()
            {
            char str[] = "ABCD1234efgh";
            int length = strlen(str);
            char * p1 = str;
            char * p2 = str + length - 1;
            while(p1 < p2)
            {
            char c = *p1;
            *p1 = *p2;
            *p2 = c;
            ++p1;
            --p2;
            }
            printf("str now is %s\n",str);
            system("pause");
            return 0;
            }
            2、有一分数序列:1/2,1/4,1/6,1/8……,用函数调用的方法,求此数列前20项的和
            #include 
            double getValue()
            {
            double result = 0;
            int i = 2;
            while(i < 42)
            {
            result += 1.0 / i;//一定要使用1.0做除数,不能用1,否则结果将自动转化成整数,
            即0.000000
            i += 2;
            }
            return result;
            }
            int main()
            {
            printf("result is %f\n", getValue());
            system("pause");
            return 0;
            }
            Top
              回复人:free131(白日?做梦!) ( 一级(初级)) 信誉:100   2006-4-17 10:18:33   
            得分:0
            ?   
            有一个数组a[1000]存放0--1000;要求每隔二个数删掉一个数,到末尾时循环至开头继续
            进行,求最后一个被删掉的数的原始下标位置。
            以7个数为例:
            {0,1,2,3,4,5,6,7} 0-->1-->2(删除)-->3-->4-->5(删除)-->6-->7-->0(删除),如
            此循环直到最后一个数被删除。
            方法1:数组
            #include 
            using namespace std;
            #define null 1000
            int main()
            {
            int arr[1000];
            for (int i=0;i<1000;++i)
            arr[i]=i;
            int j=0;
            int count=0;
            while(count<999)
            {
            while(arr[j%1000]==null)
            j=(++j)%1000;
            j=(++j)%1000;
            while(arr[j%1000]==null)
            j=(++j)%1000;
            j=(++j)%1000;
            while(arr[j%1000]==null)
            j=(++j)%1000;
            arr[j]=null;
            ++count;
            }
            while(arr[j]==null)
            j=(++j)%1000;
            cout            }方法2:链表
            #include
            using namespace std;
            #define null 0
            struct node
            {
            int data;
            node* next;
            };
            int main()
            {
            node* head=new node;
            head->data=0;
            head->next=null;
            node* p=head;
            for(int i=1;i<1000;i++)
            {
            node* tmp=new node;
            tmp->data=i;
            tmp->next=null;
            head->next=tmp;
            head=head->next;
            }
            head->next=p;
            while(p!=p->next)
            {
            p->next->next=p->next->next->next;
            p=p->next->next;
            }
            cout            return 0;
            }
            方法3:通用算法
            #include 
            #define MAXLINE 1000 //元素个数
            /*
            MAXLINE 元素个数
            a[] 元素数组
            R[] 指针场
            suffix 下标
            index 返回最后的下标序号
            values 返回最后的下标对应的值
            start 从第几个开始
            K 间隔
            */
            int find_n(int a[],int R[],int K,int& index,int& values,int s=0) {
            int suffix;
            int front_node,current_node;
            suffix=0;
            if(s==0) {
            current_node=0;
            front_node=MAXLINE-1;
            }
            else {
            current_node=s;
            front_node=s-1;
            }
            while(R[front_node]!=front_node) {
            printf("%d\n",a[current_node]);
            R[front_node]=R[current_node];
            if(K==1) {
            current_node=R[front_node];
            continue;
            }
            for(int i=0;ifront_node=R[front_node];
            }
            current_node=R[front_node];
            }
            index=front_node;
            values=a[front_node];
            return 0;
            }
            int main(void) {
            int a[MAXLINE],R[MAXLINE],suffix,index,values,start,i,K;
            suffix=index=values=start=0;
            K=2;
            for(i=0;ia[i]=i;
            R[i]=i+1;
            }
            R[i-1]=0;
            find_n(a,R,K,index,values,2);
            printf("the value is %d,%d\n",index,values);
            return 0;
            }
            试题:
            void test2()
            {
            char string[10], str1[10];
            int i;
            for(i=0; i<10; i++)
            {
            str1[i] = 'a';
            }
            strcpy( string, str1 );
            }
            解答:对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试
            者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节
            数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10 分;
            str1不能在数组内结束:因为str1的存储为:{a,a,a,a,a,a,a,a,a,a},没有'\0'(字符串
            结束符),所以不能结束
            strcpy( char *s1,char *s2)他的工作原理是,扫描s2指向的内存,逐个字符付到s1所
            指向的内存,直到碰到'\0',因为str1结尾没有'\0',所以具有不确定性,不知道他后面
            还会付什么东东。
            正确应如下
            void test2()
            {
            char string[10], str1[10];
            int i;
            for(i=0; i<9; i++)
            {
            str1[i] = 'a'+i; //把abcdefghi赋值给字符数组
            }
            str[i]='\0';//加上结束符
            strcpy( string, str1 );
            }
            第二个code题是实现strcmp
            int StrCmp(const char *str1, const char *str2)
            做是做对了,没有抄搞,比较乱
            int StrCmp(const char *str1, const char *str2)
            {
            assert(str1 && srt2);
            while (*str1 && *str2 && *str1 == *str2) {
            str1++, str2++;
            }
            if (*str1 && *str2)
            return (*str1-*str2);
            elseif (*str1 && *str2==0)
            return 1;
            elseif (*str1 = = 0 && *str2)
            return -1;
            else
            return 0;
            }
            int StrCmp(const char *str1, const char *str2)
            {
            //省略判断空指针(自己保证)
            while(*str1 && *str1++ = = *str2++);
            return *str1-*str2;
            }
            第三个code题是实现子串定位
            int FindSubStr(const char *MainStr, const char *SubStr)
            做是做对了,没有抄搞,比较乱
            int MyStrstr(const char* MainStr, const char* SubStr)
            {
            const char *p;
            const char *q;
            const char * u = MainStr;
            //assert((MainStr!=NULL)&&( SubStr!=NULL));//用断言对输入进行判断
            while(*MainStr) //内部进行递增
            {
            p = MainStr;
            q = SubStr;
            while(*q && *p && *p++ == *q++);
            if(!*q )
            {
            return MainStr - u +1 ;//MainStr指向当前起始位,u指向
            }
            MainStr ++;
            }
            return -1;
            }
            分析:
            int arr[] = {6,7,8,9,10};
            int *ptr = arr;
            *(ptr++)+=123;
            printf(“ %d %d ”, *ptr, *(++ptr));
            输出:8 8
            过程:对于*(ptr++)+=123;先做加法6+123,然后++,指针指向7;对于printf(“ %d %
            d ”, *ptr, *(++ptr));从后往前执行,指针先++,指向8,然后输出8,紧接着再输出8
            华为全套完整试题
            高级题
            6、已知一个单向链表的头,请写出删除其某一个结点的算法,要求,先找到此结点,然
            后删除。
            slnodetype *Delete(slnodetype *Head,int key){}中if(Head->number==key)
            {
            Head=Pointer->next;
            free(Pointer);
            break;
            }
            Back = Pointer;
            Pointer=Pointer->next;
            if(Pointer->number==key)
            {
            Back->next=Pointer->next;
            free(Pointer);
            break;
            }
            void delete(Node* p)
            {
            if(Head = Node)
            while(p)
            }
            有一个16位的整数,每4位为一个数,写函数求他们的和。
            解释:
            整数1101010110110111
            和 1101+0101+1011+0111
            感觉应该不难,当时对题理解的不是很清楚,所以写了一个函数,也不知道对不对。
            疑问:
            既然是16位的整数,1101010110110111是2进制的,那么函数参数怎么定义呢,请大虾指
            教。
            答案:用十进制做参数,计算时按二进制考虑。
            /* n就是16位的数,函数返回它的四个部分之和 */
            char SumOfQuaters(unsigned short n)
            {
            char c = 0;
            int i = 4;
            do
            {
            c += n & 15;
            n = n >> 4;
            } while (--i);
            return c;
            }
            有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O
            (1),使用交换,而且一次只能交换两个数.(华为)
            #include
            int main()
            {
            int a[] = {10,6,9,5,2,8,4,7,1,3};
            int len = sizeof(a) / sizeof(int);
            int temp;
            for(int i = 0; i < len; )
            {
            temp = a[a[i] - 1];
            a[a[i] - 1] = a[i];
            a[i] = temp;
            if ( a[i] == i + 1)
            i++;
            }
            for (int j = 0; j < len; j++)
            cout<
            return 0;
            }
            (慧通)
            1 写出程序把一个链表中的接点顺序倒排
            typedef struct linknode
            {
            int data;
            struct linknode *next;
            }node;
            //将一个链表逆置
            node *reverse(node *head)
            {
            node *p,*q,*r;
            p=head;
            q=p->next;
            while(q!=NULL)
            {
            r=q->next;
            q->next=p;
            p=q;
            q=r;
            }
            head->next=NULL;
            head=p;
            return head;
            }
            2 写出程序删除链表中的所有接点
            void del_all(node *head)
            {
            node *p;
            while(head!=NULL)
            {
            p=head->next;
            free(head);
            head=p;
            }
            cout<<"释放空间成功!"<}
            3两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串
            void insert(char *s, char *t, int i)
            {
            char *q = t;
            char *p =s;
            if(q == NULL)return;
            while(*p!='\0')
            {
            p++;
            }
            while(*q!=0)
            {
            *p=*q;
            p++;
            q++;
            }
            *p = '\0';
            }
            分析下面的代码:
            char *a = "hello";
            char *b = "hello";
            if(a= =b)
            printf("YES");
            else
            printf("NO");
            这个简单的面试题目,我选输出 no(对比的应该是指针地址吧),可在VC是YES 在C是NO
            lz的呢,是一个常量字符串。位于静态存储区,它在程序生命期内恒定不变。如果编译
            器优化的话,会有可能a和b同时指向同一个hello的。则地址相同。如果编译器没有优
            化,那么就是两个不同的地址,则不同
            写一个函数,功能:完成内存之间的拷贝
            memcpy source code:
            270 void* memcpy( void *dst, const void *src, unsigned int len )
            271 {
            272 register char *d;
            273 register char *s;
            27
            275 if (len == 0)
            276 return dst;
            277
            278 if (is_overlap(dst, src, len, len))
            279 complain3("memcpy", dst, src, len);
            280
            281 if ( dst > src ) {
            282 d = (char *)dst + len - 1;
            283 s = (char *)src + len - 1;
            284 while ( len >= 4 ) {
            285 *d-- = *s--;
            286 *d-- = *s--;
            287 *d-- = *s--;
            288 *d-- = *s--;
            289 len -= 4;
            290 }
            291 while ( len-- ) {
            292 *d-- = *s--;
            293 }
            294 } else if ( dst < src ) {
            295 d = (char *)dst;
            296 s = (char *)src;
            297 while ( len >= 4 ) {
            298 *d++ = *s++;
            299 *d++ = *s++;
            300 *d++ = *s++;
            301 *d++ = *s++;
            302 len -= 4;
            303 }
            304 while ( len-- ) {
            305 *d++ = *s++;
            306 }
            307 }
            308 return dst;
            309 }
            公司考试这种题目主要考你编写的代码是否考虑到各种情况,是否安全(不会溢出)
            各种情况包括:
            1、参数是指针,检查指针是否有效
            2、检查复制的源目标和目的地是否为同一个,若为同一个,则直接跳出
            3、读写权限检查
            4、安全检查,是否会溢出
            memcpy拷贝一块内存,内存的大小你告诉它
            strcpy是字符串拷贝,遇到'\0'结束
            /* memcpy ─── 拷贝不重叠的内存块 */
            void memcpy(void* pvTo, void* pvFrom, size_t size)
            {
            void* pbTo = (byte*)pvTo;
            void* pbFrom = (byte*)pvFrom;
            ASSERT(pvTo != NULL && pvFrom != NULL); //检查输入指针的有效性
            ASSERT(pbTo>=pbFrom+size || pbFrom>=pbTo+size);//检查两个指针指向的内存是否重
            叠
            while(size-->0)
            *pbTo++ == *pbFrom++;
            return(pvTo);
            }
            华为面试题:怎么判断链表中是否有环?
            bool CircleInList(Link* pHead)
            {
            if(pHead = = NULL || pHead->next = = NULL)//无节点或只有一个节点并且无自环
            return (false);
            if(pHead->next = = pHead)//自环
            return (true);
            Link *pTemp1 = pHead;//step 1
            Link *pTemp = pHead->next;//step 2
            while(pTemp != pTemp1 && pTemp != NULL && pTemp->next != NULL)
            {
            pTemp1 = pTemp1->next;
            pTemp = pTemp->next->next;
            }
            if(pTemp = = pTemp1)
            return (true);
            return (false);
            }
            两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串
            void insert(char *s, char *t, int i)
            {
            memcpy(&s[strlen(t)+i],&s[i],strlen(s)-i);
            memcpy(&s[i],t,strlen(t));
            s[strlen(s)+strlen(t)]='\0';
            }
            1。编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串
            是由同一字符组成的。
            char * search(char *cpSource, char ch)
            {
            char *cpTemp=NULL, *cpDest=NULL;
            int iTemp, iCount=0;
            while(*cpSource)
            {
            if(*cpSource == ch)
            {
            iTemp = 0;
            cpTemp = cpSource;
            while(*cpSource == ch)
            ++iTemp, ++cpSource;
            if(iTemp > iCount)
            iCount = iTemp, cpDest = cpTemp;
            if(!*cpSource)
            break;
            }
            ++cpSource;
            }
            return cpDest;
            }
            2。请编写一个 C 函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在
            位置索引值。
            int search(char *cpSource, int n, char ch)
            {
            int i;
            for(i=0; ireturn i;
            }
            一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向
            的节点?
            将这个指针指向的next节点值copy到本节点,将next指向next->next,并随后删除原next
            指向的节点。
            #include 
            void foo(int m, int n)
            {
            printf("m=%d, n=%d\n", m, n);
            }
            int main()
            {
            int b = 3;
            foo(b+=3, ++b);
            printf("b=%d\n", b);
            return 0;
            }
            输出:m=7,n=4,b=7(VC6.0)
            这种方式和编译器中得函数调用关系相关即先后入栈顺序。不过不同
            编译器得处理不同。也是因为C标准中对这种方式说明为未定义,所以
            各个编译器厂商都有自己得理解,所以最后产生得结果完全不同。
            因为这样,所以遇见这种函数,我们首先要考虑我们得编译器会如何处理
            这样得函数,其次看函数得调用方式,不同得调用方式,可能产生不同得
            结果。最后是看编译器优化。
            2.写一函数,实现删除字符串str1中含有的字符串str2.
            第二个就是利用一个KMP匹配算法找到str2然后删除(用链表实现的话,便捷于数组)
            /*雅虎笔试题(字符串操作)
            给定字符串A和B,输出A和B中的最大公共子串。
            比如A="aocdfe" B="pmcdfa" 则输出"cdf"
            */
            //Author: azhen
            #include
            #include
            #include
            char *commanstring(char shortstring[], char longstring[])
            {
            int i, j;
            char *substring=malloc(256);
            if(strstr(longstring, shortstring)!=NULL) //如果……,那么返回shortstring
            return shortstring;
            for(i=strlen(shortstring)-1;i>0; i--) //否则,开始循环计算
            {
            for(j=0; j<=strlen(shortstring)-i; j++){
            memcpy(substring, &shortstring[j], i);
            substring[i]='\0';
            if(strstr(longstring, substring)!=NULL)
            return substring;
            }
            }
            return NULL;
            }
            main()
            {
            char *str1=malloc(256);
            char *str2=malloc(256);
            char *comman=NULL;
            gets(str1);
            gets(str2);
            if(strlen(str1)>strlen(str2)) //将短的字符串放前面
            comman=commanstring(str2, str1);
            else
            comman=commanstring(str1, str2);
            printf("the longest comman string is: %s\n", comman);
            }
            11.写一个函数比较两个字符串str1和str2的大小,若相等返回0,若str1大于
            str2返回1,若str1小于str2返回-1
            int strcmp ( const char * src,const char * dst)
            {
            int ret = 0 ;
            while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
            {
            ++src;
            ++dst;
            }
            if ( ret < 0 )
            ret = -1 ;
            else if ( ret > 0 )
            ret = 1 ;
            return( ret );
            }
            3,求1000!的未尾有几个0(用素数相乘的方法来做,如72=2*2*2*3*3);
            求出1->1000里,能被5整除的数的个数n1,能被25整除的数的个数n2,能被125整除的数的
            个数n3,
            能被625整除的数的个数n4.
            1000!末尾的零的个数=n1+n2+n3+n4;
            #include
            #define NUM 1000
            int find5(int num){
            int ret=0;
            while(num%5==0){
            num/=5;
            ret++;
            }
            return ret;
            }
            int main(){
            int result=0;
            int i;
            for(i=5;i<=NUM;i+=5)
            {
            result+=find5(i);
            }
            printf(" the total zero number is %d\n",result);
            return 0;
            }
            1. 有双向循环链表结点定义为:
            struct node
            { int data;
            struct node *front,*next;
            };
            有两个双向循环链表A,B,知道其头指针为:pHeadA,pHeadB,请写一函数将两链表中
            data值相同的结点删除
            BOOL DeteleNode(Node *pHeader, DataType Value)
            {
            if (pHeader == NULL) return;
            BOOL bRet = FALSE;
            Node *pNode = pHead;
            while (pNode != NULL)
            {
            if (pNode->data == Value)
            {
            if (pNode->front == NULL)
            {
            pHeader = pNode->next;
            pHeader->front = NULL;
            }
            else
            {
            if (pNode->next != NULL)
            {
            pNode->next->front = pNode->front;
            }
            pNode->front->next = pNode->next;
            }
            Node *pNextNode = pNode->next;
            delete pNode;
            pNode = pNextNode;
            bRet = TRUE;
            //不要break或return, 删除所有
            }
            else
            {
            pNode = pNode->next;
            }
            }
            return bRet;
            }
            void DE(Node *pHeadA, Node *pHeadB)
            {
            if (pHeadA == NULL || pHeadB == NULL)
            {
            return;
            }
            Node *pNode = pHeadA;
            while (pNode != NULL)
            {
            if (DeteleNode(pHeadB, pNode->data))
            {
            if (pNode->front == NULL)
            {
            pHeadA = pNode->next;
            pHeadA->front = NULL;
            }
            else
            {
            pNode->front->next = pNode->next;
            if (pNode->next != NULL)
            {
            pNode->next->front = pNode->front;
            }
            }
            Node *pNextNode = pNode->next;
            delete pNode;
            pNode = pNextNode;
            }
            else
            {
            pNode = pNode->next;
            }
            }
            }
            2. 编程实现:找出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串
            为"cad"
            int GetCommon(char *s1, char *s2, char **r1, char **r2)
            {
            int len1 = strlen(s1);
            int len2 = strlen(s2);
            int maxlen = 0;
            for(int i = 0; i < len1; i++)
            {
            for(int j = 0; j < len2; j++)
            {
            if(s1[i] == s2[j])
            {
            int as = i, bs = j, count = 1;
            while(as + 1 < len1 && bs + 1 < len2 && s1[++as] == s2[++bs])
            count++;
            if(count > maxlen)
            {
            maxlen = count;
            *r1 = s1 + i;
            *r2 = s2 + j;
            }
            }
            }
            }
            3. 编程实现:把十进制数(long型)分别以二进制和十六进制形式输出,不能使用printf
            系列库函数
            char* test3(long num) {
            char* buffer = (char*)malloc(11);
            buffer[0] = '0';
            buffer[1] = 'x';
            buffer[10] = '\0';
            char* temp = buffer + 2;
            for (int i=0; i < 8; i++) {
            temp[i] = (char)(num<<4*i>>28);
            temp[i] = temp[i] >= 0 ? temp[i] : temp[i] + 16;
            temp[i] = temp[i] < 10 ? temp[i] + 48 : temp[i] + 55;
            }
            return buffer;
            }
            输入N, 打印 N*N 矩阵
            比如 N = 3,打印:
            1 2 3
            8 9 4
            7 6 5
            N = 4,打印:
            1 2 3 4
            12 13 14 5
            11 16 15 6
            10 9 8 7
            解答:
            1 #define N 15
            int s[N][N];
            void main()
            {
            int k = 0, i = 0, j = 0;
            int a = 1;
            for( ; k < (N+1)/2; k++ )
            {
            while( j < N-k ) s[i][j++] = a++; i++; j--;
            while( i < N-k ) s[i++][j] = a++; i--; j--;
            while( j > k-1 ) s[i][j--] = a++; i--; j++;
            while( i > k ) s[i--][j] = a++; i++; j++;
            }
            for( i = 0; i < N; i++ )
            {
            for( j = 0; j < N; j++ )
            cout << s[i][j] << '\t';
            cout << endl;
            }
            }
            2 define MAX_N 100
            int matrix[MAX_N][MAX_N];
            /*
            *(x,y):第一个元素的坐标
            * start:第一个元素的值
            * n:矩阵的大小
            */
            void SetMatrix(int x, int y, int start, int n) {
            int i, j;
            if (n <= 0) //递归结束条件
            return;
            if (n == 1) { //矩阵大小为1时
            matrix[x][y] = start;
            return;
            }
            for (i = x; i < x + n-1; i++) //矩阵上部
            matrix[y][i] = start++;
            for (j = y; j < y + n-1; j++) //右部
            matrix[j][x+n-1] = start++;
            for (i = x+n-1; i > x; i--) //底部
            matrix[y+n-1][i] = start++;
            for (j = y+n-1; j > y; j--) //左部
            matrix[j][x] = start++;
            SetMatrix(x+1, y+1, start, n-2); //递归
            }
            void main() {
            int i, j;
            int n;
            scanf("%d", &n);
            SetMatrix(0, 0, 1, n);
            //打印螺旋矩阵
            for(i = 0; i < n; i++) {
            for (j = 0; j < n; j++)
            printf("%4d", matrix[i][j]);
            printf("\n");
            }
            }
            斐波拉契数列递归实现的方法如下:
            int Funct( int n )
            {
            if(n==0) return 1;
            if(n==1) return 1;
            retrurn Funct(n-1) + Funct(n-2);
            }
            请问,如何不使用递归,来实现上述函数?
            请教各位高手!
            解答:int Funct( int n ) // n 为非负整数
            {
            int a=0;
            int b=1;
            int c;
            if(n==0) c=1;
            else if(n==1) c=1;
            else for(int i=2;i<=n;i++) //应该n从2开始算起
            {
            c=a+b;
            a=b;
            b=c;
            }
            return c;
            }
            解答:
            现在大多数系统都是将低字位放在前面,而结构体中位域的申明一般是先声明高位。
            100 的二进制是 001 100 100
            低位在前 高位在后
            001----s3
            100----s2
            100----s1
            所以结果应该是 1
            如果先申明的在低位则:
            001----s1
            100----s2
            100----s3
            结果是 4
            1、原题跟little-endian,big-endian没有关系
            2、原题跟位域的存储空间分配有关,到底是从低字节分配还是从高字节分配,从Dev 
            C++和VC7.1上看,都是从低字节开始分配,并且连续分配,中间不空,不像谭的书那样
            会留空位
            3、原题跟编译器有关,编译器在未用堆栈空间的默认值分配上有所不同,Dev C++未用
            空间分配为
            01110111b,VC7.1下为11001100b,所以在Dev C++下的结果为5,在VC7.1下为1。
            注:PC一般采用little-endian,即高高低低,但在网络传输上,一般采用big-endian,
            即高低低高,华为是做网络的,所以可能考虑big-endian模式,这样输出结果可能为4
            判断一个字符串是不是回文
            int IsReverseStr(char *aStr)
            {
            int i,j;
            int found=1;
            if(aStr==NULL)
            return -1;
            j=strlen(aStr);
            for(i=0;iif(*(aStr+i)!=*(aStr+j-i-1))
            {
            found=0;
            break;
            }
            return found;
            }
            Josephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人
            从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出
            列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
            数组实现:
            #include 
            #include 
            int Josephu(int n, int m)
            {
            int flag, i, j = 0;
            int *arr = (int *)malloc(n * sizeof(int));
            for (i = 0; i < n; ++i)
            arr[i] = 1;
            for (i = 1; i < n; ++i)
            {
            flag = 0;
            while (flag < m)
            {
            if (j == n)
            j = 0;
            if (arr[j])
            ++flag;
            ++j;
            }
            arr[j - 1] = 0;
            printf("第%4d个出局的人是:%4d号\n", i, j);
            }
            free(arr);
            return j;
            }
            int main()
            {
            int n, m;
            scanf("%d%d", &n, &m);
            printf("最后胜利的是%d号!\n", Josephu(n, m));
            system("pause");
            return 0;
            }
            链表实现:
            #include 
            #include 
            typedef struct Node
            {
            int index;
            struct Node *next;
            }JosephuNode;
            int Josephu(int n, int m)
            {
            int i, j;
            JosephuNode *head, *tail;
            head = tail = (JosephuNode *)malloc(sizeof(JosephuNode));
            for (i = 1; i < n; ++i)
            {
            tail->index = i;
            tail->next = (JosephuNode *)malloc(sizeof(JosephuNode));
            tail = tail->next;
            }
            tail->index = i;
            tail->next = head;
            for (i = 1; tail != head; ++i)
            {
            for (j = 1; j < m; ++j)
            {
            tail = head;
            head = head->next;
            }
            tail->next = head->next;
            printf("第%4d个出局的人是:%4d号\n", i, head->index);
            free(head);
            head = tail->next;
            }
            i = head->index;
            free(head);
            return i;
            }
            int main()
            {
            int n, m;
            scanf("%d%d", &n, &m);
            printf("最后胜利的是%d号!\n", Josephu(n, m));
            system("pause");
            return 0;
            }
            已知strcpy函数的原型是:
            char * strcpy(char * strDest,const char * strSrc);
            1.不调用库函数,实现strcpy函数。
            2.解释为什么要返回char *。
            解说:
            1.strcpy的实现代码
            char * strcpy(char * strDest,const char * strSrc)
            {
            if ((strDest==NULL)||(strSrc==NULL)) file://[/1]
            throw "Invalid argument(s)"; //[2]
            char * strDestCopy=strDest; file://[/3]
            while ((*strDest++=*strSrc++)!='\0'); file://[/4]
            return strDestCopy;
            }
            错误的做法:
            [1]
            (A)不检查指针的有效性,说明答题者不注重代码的健壮性。
            (B) 检查指针的有效性时使用((!strDest)||(!strSrc))或(!(strDest&&strSrc)),说明
            答题者对C语言中类型的隐式转换没有深刻认识。在本例中char *转换为bool即是类型隐
            式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。所以C++专
            门增加了bool、true、false 三个关键字以提供更安全的条件表达式。
            (C)检查指针的有效性时使用((strDest==0)||(strSrc==0)),说明答题者不知道使用常
            量的好处。直接使用字面常量(如本例中的0)会减少程序的可维护性。0虽然简单,但
            程序中可能出现很多处对指针的检查,万一出现笔误,编译器不能发现,生成的程序内
            含逻辑错误,很难排除。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。
            [2]
            (A)return new string("Invalid argument(s)");,说明答题者根本不知道返回值的用
            途,并且他对内存泄漏也没有警惕心。从函数中返回函数体内分配的内存是十分危险的
            做法,他把释放内存的义务抛给不知情的调用者,绝大多数情况下,调用者不会释放内
            存,这导致内存泄漏。
            (B)return 0;,说明答题者没有掌握异常机制。调用者有可能忘记检查返回值,调用者
            还可能无法检查返回值(见后面的链式表达式)。妄想让返回值肩负返回正确值和异常
            值的双重功能,其结果往往是两种功能都失效。应该以抛出异常来代替返回值,这样可
            以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。
            [3]
            (A)忘记保存原始的strDest值,说明答题者逻辑思维不严密。
            [4]
            (A)循环写成while (*strDest++=*strSrc++);,同[1](B)。
            (B)循环写成while (*strSrc!='\0') *strDest++=*strSrc++;,说明答题者对边界条件
            的检查不力。循环体结束后,strDest字符串的末尾没有正确地加上'\0'。 
阅读(5963) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~