电脑硬盘坏过一次,请人挽回了些数据,但很多东西还是丢了。偶然翻出来的这些源码,是以前整理的一些面试中常用的编程题,在VC上测试过,但不保证完全没有问题。发到网上就不怕再坏硬盘了。
1.写一函数int fun(char *p)判断一字符串是否为回文,是返回1,不是返回0,出错返回-1
//////////答案:一、
int fun(char *p)
{
if(p==NULL)
return -1;
else
{
int length = 0;
int i = 0;
int judge = 1;
length = (int)strlen(p);
for(i=0; i <length/2; i++)
{
if(p[i] != p[length-1-i])
judge = 0;
break;
}
if(judge == 0)
return 0;
else
return 1;
}
//////////答案:二、
int fun1(char *p)
{
if(p==NULL)
return -1;
int len = (int)strlen(p) - 1;
char *q = p + len;
while (p < q)
{
if ((*p++) != (*q--))
return 0;
}
return 1;
}
2.类的知识 (非常不错的一道题目)..
#include <iostream.h>
class human
{
public:
human()
{
human_num++;
}; //默认构造函数
static int human_num; //静态成员
~human()
{
human_num--;
print();
}
void print() //
{
cout<<"human num is: "<<human_num<<endl;
}
protected:
private:
};
int human::human_num = 0; //类中静态数据成员在外部定义,仅定义一次
human f1(human x)
{
x.print();
return x;
}
int main(int argc, char* argv[])
{
human h1; //调用默认构造函数,human_num变为1
h1.print(); // 打印Human_man:1
human h2 = f1(h1); //先调用函数f1(),输出human_num:1,而后输出human_num为0,
h2.print();//打印输出:human_num:0
return 0;
} //依次调用两个析构函数:输出:human_num:-1,human_num:-2;
输出:
1
1
0
0
-1
-2
----------------------------
分析:
human h1; //调用构造函数,---hum_num = 1;
h1.print(); //输出:"human is 1"
human h2 = f1(h1); //再调用f1(h1)的过程中,由于函数参数是按值传递对象,调用默认的复制构造函数,h2并没有调用定义的构造函数.
3.深度遍历二叉树。
struct Node
{
int Data; //我自己添加的,方便测试
Node *Parent;
Node *Left, *Right;
};
void Through(Node *Root)
{
cout<<Root->Data<<endl;
if(Root->Left != NULL)
Through(Root->Left);
if(Root->Right != NULL)
Through(Root->Right);
}
4.输入年月日时分秒,输出年月日时分秒的下一秒,输出仍然在原内存空间
/*输入年月日时分秒,输出年月日时分秒的下一秒,输出仍然在原内存空间*/
void NextMinute(int *nYear,int *nMonth,int *nDate,int *nHour,int *nMinute,int *nSecond)
{
int nDays;
(*nSecond)++; // 秒加1
if(*nSecond>=60) // 秒满60,做出特殊处理,下面时,日,月等类同
{
*nSecond=0;
(*nMinute)++;
if(*nMinute>=60)
{
*nMinute=0;
(*nHour)++;
if(*nHour>=24)
{
*nHour=0;
(*nDate)++;
switch(*nMonth)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
nDays=31;
break;
case 2:// 判断闰年
if(*nYear%400==0 || *nYear%100!=0&&*nYear%4==0)
{
nDays=29;
}
else
{
nDays=28;
}
break;
default:
nDays=30;
break;
}
if(*nDate>nDays)
{
*nDate=1;
(*nMonth)++;
if(*nMonth>12)
{
*nMonth=1;
(*nYear)++;
}
}
}
}
}
}
5.atoi 函数
/////** atoi 函数 **/////
int my_atoi01(const char *str)
{
long int v=0;
int sign = 0;
while ( *str == ' ')
str++;
if(*str == '-'||*str == '+')
sign = *str++;
while (isdigit(*str))
{
v = v*10 + *str - '0';
str++;
}
return sign == '-' ? -v:v;
}
6.itoa 函数
/////** itoa 函数 **/////
char *my_itoa(int val, char *buf, int radix)
{
char *p, *first, temp;
int digital;
p = buf;
if (val < 0)
{
*p++ = '-';
val = -val;
}
first = p;
do
{
digital = val%radix;
val /= radix;
if (digital > 9)
*p++ = (char)(digital - 10 + 'A');
else
*p++ = (char)(digital + '0');
}while(val > 0);
*p-- = '\0';
do
{
temp = *p;
*p = *first;
*first = temp;
p--;
first++;
}while(first < p);
return buf;
}
7.atol 函数
/////** atol 函数 **/////
long my_atol( const char *nptr )
{
int c; /* current char */
long total; /* current total */
int sign; /* if '-', then negative, otherwise positive */
/* skip whitespace */
while ( isspace((int)(unsigned char)*nptr) )
++nptr;
c = (int)(unsigned char)*nptr++;
sign = c; /* save sign indication */
if (c == '-' || c == '+')
c = (int)(unsigned char)*nptr++; /* skip sign */
total = 0;
while (isdigit(c))
{
total = 10 * total + (c - '0'); /* accumulate digit */
c = (int)(unsigned char)*nptr++; /* get next char */
}
if (sign == '-')
return -total;
else
return total; /* return result, negated if necessary */
}
8.strlen 函数
/////** strlen 函数 **/////
size_t strlen ( const char * str )
{
const char *eos = str;
while( *eos++ )
;
return( (int)(eos - str - 1) );
}
9.strstr函数
/////** strstr函数 **/////
char * strstr (const char * str1,const char * str2 )
{
char *cp = (char *) str1;
char *s1, *s2;
if ( !*str2 )
return((char *)str1);
while (*cp)
{
s1 = cp;
s2 = (char *) str2;
while ( *s1 && *s2 && !(*s1-*s2) )
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return(NULL);
}
10. strcat函数
/////** strcat函数 **/////
char * strcat (char * dst,const char * src )
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
11. strncat函数
/////** strncat函数 **/////
char * strncat (char * front,const char * back,size_t count )
{
char *start = front;
while (*front++)
;
front--;
while (count--)
if (!(*front++ = *back++))
return(start);
*front = '\0';
return(start);
}
12. strcpy函数
/////** strcpy函数 **/////
char * strcpy(char * dst, const char * src)
{
char * cp = dst;
while( *cp++ = *src++ )
; /* Copy src over dst */
return( dst );
}
13. strncpy函数
/////** strncpy函数 **/////
char * strncpy (char * dest,const char * source,size_t count)
{
char *start = dest;
while (count && (*dest++ = *source++)) /* copy string */
count--;
if (count) /* pad out with zeroes */
while (--count)
*dest++ = '\0';
return(start);
}
14. strcmp函数
/////** strcmp函数 **/////
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 );
}
15. strncmp函数
/////** strncmp函数 **/////
int strncmp (const char * first,const char * last,size_t count)
{
if (!count)
return(0);
while (--count && *first && *first == *last)
{
first++;
last++;
}
return( *(unsigned char *)first - *(unsigned char *)last );
}
16. memset函数
/////** memset函数 **/////
void * memset (void *dst,int val,size_t count)
{
void *start = dst;
while (count--)
{
*(char *)dst = (char)val;
dst = (char *)dst + 1;
}
return(start);
}
17. memcpy函数
/////** memcpy函数 **/////
void * memcpy (void * dst, const void * src,size_t count)
{
void * ret = dst;
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}
18. memcmp函数
/////** memcmp函数 **/////
int memcmp ( const void * buf1, const void * buf2, size_t count )
{
if (!count)
return(0);
while ( --count && *(char *)buf1 == *(char *)buf2 ) {
buf1 = (char *)buf1 + 1;
buf2 = (char *)buf2 + 1;
}
return( *((unsigned char *)buf1) - *((unsigned char *)buf2) );
}
19.编写用C语言实现的求n阶阶乘问题的递归算法:
答:
long int fact(int n)
{
if(n==0||n==1)
return 1;
else
return n*fact(n-1);
}
20.二分查找算法:
1) 递归方法实现:
/*在下届为low,上界为high的数组a中折半查找数据元素x*/
int BSearch(int a[],int x,int low,int high)
{
int mid;
if(low>high)
return -1;
mid=(low+high)/2;
if(x==a[mid])
return mid;
if(x<a[mid])
return(BSearch(a,x,low,mid-1));
else
return(BSearch(a,x,mid+1,high));
}
2) 非递归方法实现:
//////2) 非递归方法实现:
int BSearch1(int a[], int key,int n)
{
int low,high,mid;
low=0;
high=n-1;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid]==key)
return mid;
else
if(a[mid]<key)
low=mid+1;
else
high=mid-1;
}
return -1;
}
21.递归计算如下递归函数的值(斐波拉契):
f(1)=1
f(2)=1
f(n)=f(n-1)+f(n-2) n>2
解:非递归算法:
int f(int n)
{
if(n==1 || n==2)
return 1;
int i,s,s1,s2;
s1=1; /*s1用于保存f(n-1)的值*/
s2=1; /*s2用于保存f(n-2)的值*/
s=1;
for(i=3;i<=n;i++)
{
//s=s2+s1;
//s2=s1;
//s1=s;
s = s2 + s1; ////我改的代码,感觉读得懂些
s1 = s2;
s2 = s;
}
return(s);
}
递归算法:
int f1(int n)
{
if(n==1||n==2)
return 1;
else
return (f1(n-1)+f1(n-2));
}
22.冒泡排序:
答:
///////时间复杂度为0(n*n);
void BubbleSort(int x[],int n)
{
int i,j;
int temp;
for(i=1;i<n;i++)
for(j=0;j<n-i;j++)
{
if(x[j]>x[j+1])
{
temp=x[j];
x[j]=x[j+1];
x[j+1]=temp;
}
}
}
23.C语言 文件读写
#include "stdio.h"
main()
{
FILE *fp;
char ch,filename[10];
scanf("%s",filename);
if((fp=fopen(filename,"w")==NULL)
{
printf("cann't open filen");
exit(0);
}
ch=getchar();
while(ch!='#')
{
fputc(ch,fp);
putchar(ch);
ch=getchar();
}
fclose(fp);
}
24.编写反转字符串的程序,要求优化速度、优化空间。
/////反转字符串的程序,要求优化速度和空间
void str_revert(char* argv,int len)
{
int i = 0;
int mid = len/2;
char *head = argv;
char *end = argv+len-1;
char tmp = 0;
for(i=0; i<mid; i++)
{
tmp = *head;
*head = *end;
*end = tmp;
head++;
end--;
}
}
25.给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。
//////洗牌算法
struct pukepai{
char d; //点
char s; //花色
};
char dian(int i)
{
switch(i)
{
case 0:
return 'K';
case 1:
return 'A';
case 10:
return 'T';
case 11:
return 'J';
case 12:
return 'Q';
default:
return i+48; ////???????????????不懂
}
}
void display()
{
pukepai p[54];
int temp[54],tem,i,j;
for(i=0;i<54;i++)
temp[i]=i+1;
srand(time(0));
for(i=0;i<54;i++) //洗牌 1---54的随机数
{
tem=rand()%54;
j=temp[i];
temp[i]=temp[tem];
temp[tem]=j;
}
for(i=0;i<54;i++) //赋值 并显示
{
if(temp[i]==54)
p[i].d='S',p[i].s=0; //大S
else
if(temp[i]==53)
p[i].d='s',p[i].s=0; //小s
else
{
p[i].d=dian(temp[i]%13);
p[i].s=(temp[i]-1)/13+3;
}
}
for(i=0;i<54;i++)
{
cout<<p[i].s<<p[i].d<<" ";
if((i+1)%5 ==0 )
cout<<endl;
}
cout<<endl;
26.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
anSwer 记住,这种题目往往就是考你对边界的考虑情况。编程除了技术上的熟练以外,细心也是非常重要的。其实很多编程的大师可能并不是有特别的技术,往往就是他们非常的耐心和细心,记住:编程是计算机科学中最基本的工作,它是最容易去掌握的,耐心点,细心点你一定能够学好它。代码看下面:
char* myStrcpy(char* s,char* a,char* b,char n)
{
int aLen = strlen(a),bLen = strlen(b);
if(n > aLen || n > bLen)
return NULL; // Error
for(int i = 0;i < aLen + bLen - n;i++)
if(i < aLen - n)
s[i] = a[i];
else
s[i] = b[i - aLen + n];
s[i] = '\0';
return s;
}
27.怎样编写一个程序,把一个有序整数数组放到二叉树中?
ANSWER :二叉搜索树的建树方法。简单的递归结构。实在不理解,干脆记下来好了。关于树的算法设计一定要联想到递归,因为树本身就是递归的定义。这里的递归应该是理所当然的吧,不过,学会把递归改称非递归也是一种必要的技术。毕竟,递归会造成栈溢出,关于系统底层的程序中不到非不得以最好不要用。但是对某些数学问题,就一定要学会用递归去解决。
void insertNode(bTree** root,int val)
{
bTree* newNode = (bTree* ) malloc(sizeof(bTree));
newNode->data = val;
newNode->lChild = NULL;
newNode->rChild = NULL;
if(!(*root))
*root = newNode;
else
if(newNode->data < (*root)->data)
insertNode(&(*root)->lChild,val);
else
insertNode(&(*root)->rChild,val);
}
28.怎样从顶部开始逐层打印二叉树结点数据?请编程。
ANSWER 二叉树的层次遍历没什么好说的,如果你不会还是早点把基础复习一下。一个劲的往后学,才会发现原来最最重要的还是以前最基础最简单的。
typedef struct myBinaryTree
{
int data;
struct myBinaryTree* lChild;
struct myBinaryTree* rChild;
} bTree;
struct myQueen
{
bTree* que[QSIZE];
int front;
int rear;
} binQueue; // Global var
void initQueue()
{
// front == real makes the queue empty
binQueue.rear = QSIZE - 1;
binQueue.front = binQueue.rear;
for(int i = 0;i < QSIZE;i++)
binQueue.que[i] = NULL;
}
int enQueue(bTree* newNode)
{
if(binQueue.front >= 1)
binQueue.que[binQueue.front--] = newNode;
else
return 0;
return 1;
}
bTree* deQueue()
{
int t;
if(binQueue.front != binQueue.rear)
{
t = binQueue.rear;
binQueue.rear--;
return binQueue.que[t];
}
else
return NULL;
}
int levelTraversal(bTree** root)
{
initQueue();
bTree* lc = (bTree* ) malloc(sizeof(bTree));
bTree* rc = (bTree* ) malloc(sizeof(bTree));
bTree* p = (bTree* ) malloc(sizeof(bTree));
if((!lc) || (!rc) || (!p))
{
printf("OVERFLOW\n");
exit(OVERFLOW); // Allocation Error
}
p = *root;
if(!p)
{
printf("Empty Tree,build it first !\n");
return 0;
}
enQueue(p); // enqueue the root of the tree
while (binQueue.front != binQueue.rear)
{
p = deQueue();
printf("%d ",p->data);
lc = p->lChild;
rc = p->rChild;
if(lc != NULL)
enQueue(lc);
if(rc != NULL)
enQueue(rc);
}
printf("\n");
return 1;
}
29.怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)?
ANSWER 前面说了,最基本的是最重要的。线性数据结构是学习数据结构的入门,一定要掌握好。微软的题目还是跟国内的公司不一样。国内的一上来就是些概念,跟考历史一样。
typedef struct listNode
{
struct listNode* link;
int data;
}node;
node* getNode(node* newNode,int val)
{
if(!newNode)
exit(OVERFLOW);
newNode->link = NULL;
newNode->data = val;
return newNode;
}
/*
Insert a new node after p
*/
int insertNode(node* prev,node* newNode)
{
if(!prev) return 0;
newNode->link = prev->link;
prev->link = newNode;
return 1;
}
/*
delete the node after the node prev
*/
int eraseNode(node*prev,node* p)
{
if(p == NULL)
return 0;
prev->link = p->link;
free(p);
return 1;
}
void buildList(node* head)
{
int value;
node* newNode = (node* ) malloc(sizeof(node));
node* p = head;
scanf("%d",&value);
while(value != -1){
newNode = getNode(newNode,value);
insertNode(p,newNode);
p = p->link;
newNode = (node* ) malloc(sizeof(node));
scanf("%d",&value);
}
}
int reverseList(node* head)
{
node* p = head->link;
node* q = p->link;
if(p == NULL){
printf("The list is empty!\n");
return 0;
}
while(q != NULL){
node* newNode = (node* ) malloc(sizeof(node));
newNode = getNode(newNode,q->data);
insertNode(head,newNode);
eraseNode(p,q);
q = (node* ) malloc(sizeof(node)); // Allocate again
q = p->link;
}
p->link = NULL;
return 1;
}
30.将以空格为分隔符分隔的字符串逆序打印,但单词不逆序。例如“Hello world Welcome to China”的打印结果为“China to Welcome world Hello”。
void print_word(const char * str, int start, int end)
{
int i;
for (i = start; i < end; ++i)
{
printf("%c", str[i]);
}
}
/* Reversely print string str. */
void reversely_print_string(const char * str)
{
int len, i, end;
len = strlen(str);
end = len;
for (i = len - 1; i >= 0; --i)
{
if (' ' == str[i])
{
/* Print the word after this space. */
print_word(str, i + 1, end);
/* Print the space. */
printf("%c", str[i]);
/* Set the right boundary of the previous word. */
end = i;
}
}
/* Print the first word. */
print_word(str, 0, end);
}
31.编写类String 的构造函数、析构函数和赋值函数
class String
{
public:
String(const char *str = NULL); // 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void); // 析构函数
String & operator =(const String &other); // 赋值函数
private:
char *m_data; // 用于保存字符串
};
// 请编写String 的上述4 个函数。
// 标准答案:
// String 的析构函数
String::~String(void) // 3 分
{
delete [] m_data;
// 由于m_data 是内部数据类型,也可以写成 delete m_data;
}
// String 的普通构造函数
String::String(const char *str) // 6 分
{
if(str==NULL)
{
m_data = new char[1]; // 若能加 NULL 判断则更好
*m_data = '\0';
}
else
{
int length = strlen(str);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, str);
}
}
// 拷贝构造函数
String::String(const String &other) // 3 分
{
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);
}
// 赋值函数
String & String::operator =(const String &other) // 13 分
{
// (1) 检查自赋值 // 4 分
if(this == &other)
return *this;
// (2) 释放原有的内存资源 // 3 分
delete [] m_data;
// (3)分配新的内存资源,并复制内容 // 3 分
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);
// (4)返回本对象的引用 // 3 分
return *this;
}