1.leetcode
1 2 3 4 5 6
| digit = x % 10 x /= 10
rev = rev * 10 + digit
|
例题:力扣7:回文数(逆序数字)
也是西南交大2005年程序题第1题
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Solution { public: int reverse(int x) { long outcome=0; while(x) { int i=x%10; outcome=outcome*10+i; x/=10; } return outcome<INT_MIN || outcome>INT_MAX?0:outcome; } };
|
2.王道
3.天勤
例6-1:求二叉树存储的算术表达式的值
题目:表达式存储在二叉树中,编写算法求值。
分析:先求左再求右,读取根结点符号,计算值。所以采用后序遍历
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| typedef struct BTNode { struct BTNode* lchild, * rchild; char data; }BTNode;
int op(int A, int B, char C) {};
int comp(BTNode* p) { int A, B; if (p == NULL) { return 0; }
if (p->lchild == NULL && p->rchild == NULL) { return p->data - '0'; }
A = comp(p->lchild); B = comp(p->rchild); return op(A, B, p->data); }
|
例6-3:找指定结点(剪枝操作)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| typedef struct BTNode { struct BTNode* lchild, * rchild; char data; }BTNode;
void Search(BTNode* p, BTNode*& q, int key) { if (p == NULL) { return; } if (p->data == key) { q = p; } else { Search(p->lchild, q, key); if (q == NULL) { Search(p->rchild, q, key); } } }
|
例6-3:求二叉树宽度
宽度:结点数最多一层上的结点个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| #define maxSize 100
typedef struct BTNode { struct BTNode* lchild, * rchild; char data; }BTNode;
typedef struct //非循环队列的队列元素,存储结点指针以及层号 { BTNode* p; int lno; }St;
int MaxNode(BTNode* b) { St que[maxSize]; int front = 0, rear = 0;
int Lno = 0, i, j, n, max = 0; BTNode* q;
if (b != NULL) { ++rear; que[rear].p = b; que[rear].lno = 1;
while (front != rear) { ++front; q = que[front].p; Lno = que[front].lno; if (q->lchild != NULL) { ++rear; que[rear].p = q->lchild; que[rear].lno = Lno + 1; } if (q->rchild != NULL) { ++rear; que[rear].p = q->lchild; que[rear].lno = Lno + 1; } }
for (i = 1; i <= Lno; i++) { n = 0; for (j = 0; j < rear; j++) { if (que[j].lno == i) { ++n; } }
if (max < n) { max = n; } } return max; } else return 0; }
|
缺陷:效率不太好,还可以优化
习题2.1.5:填充parent域
题目:二叉树增加parent域,设计算法给每个结点parent域赋值,并输出所以结点到根结点路径
分析:给parent赋值可以在遍历时传入父节点指针
打印路径即找到结点一直访问parent域
打印全部路径采用遍历方式来完成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include<stdio.h> #include<malloc.h> #include <iostream> using namespace std;
typedef struct BTNode { struct BTNode* lchild, * rchild, * parent; char data; }BTNode;
void triBtree(BTNode* p, BTNode* q) { if (p != NULL) { p->parent = q; q = p; triBtree(p->lchild, q); triBtree(p->rchild, q); } }
void printPath(BTNode* p) { while (p != NULL) { cout << p->data << " " << endl; p = p->parent; } }
void allpath(BTNode* p) { if (p != NULL) { printPath(p);
allpath(p->lchild); allpath(p->rchild); } }
|
习题2.1.7:输出指定结点层号
分析:看书
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include<stdio.h> #include<malloc.h> #include <iostream> using namespace std;
typedef struct BTNode { struct BTNode* lchild, * rchild; char data; }BTNode;
int L = 1; void leno(BTNode* p, char x) { if (p != NULL) { if (p->data == x) { cout << L << endl; } } ++L; leno(p->lchild, x); leno(p->rchild, x); --L; }
|
习题2.2.1:输出根结点到每个叶子结点路径
分析:看书
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<stdio.h> #include<malloc.h> #include <iostream> using namespace std;
#define maxSize 50
typedef struct BTNode { struct BTNode* lchild, * rchild; char data; }BTNode;
int i; int top=0; char pathStack[maxSize]; void allpath(BTNode* p) { if (p != NULL) { pathStack[top++] = p->data; if (p->lchild == NULL && p->rchild == NULL) { for (i = 0; i < top; i++) { cout << pathStack[i]; } }
allpath(p->lchild); allpath(p->rchild); --top; } }
|
4.西南交大2005年840程序题
第2题:求字符串中出现整数个数
错误:-号在数字中间和数字末尾会输出错误
题目:输入一个字符串,内有数字和非数字字符,如b56x6g*6454er790v将其中连续数字作为一个长整型数依次存入数组a中,例:56存入a[0],6存入a[1]。。。统计有多少整数,并输出。假设不存在溢出情况,字符串中存在“-”号要将其后数字看作负数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #include<stdio.h> #include<string.h> #include<ctype.h>
int myatoi2(char* a) { if(a[0]!='-') { int len=strlen(a),i,j,n=0; int sum=0; for(i=0;i<len;i++) { int bitsum; bitsum=a[i]-'0'; for(j=0;j<len-i-1;j++) { bitsum*=10; } sum+=bitsum; } return sum; } else if(a[0]=='-' && a[1]>='0'&&a[1]<='9') { return -myatoi2(&(a[1])); } else { return myatoi2(&(a[1])); } }
void getnum(char* str,int* num) { int i=0,j=0,k=0,m=0; char temp[10]={0}; while(str[i]!='\0') { if(str[i]>='0'&&str[i]<='9'||str[i]=='-') { if(m!=0&&str[i]=='-') { if(m!=1) { num[k++]=myatoi2(temp); } memset(temp,0,10); j=0; m=0; continue; } m++; temp[j++]=str[i]; } else if((str[i-1]>='0' && str[i-1]<='9')) { num[k++]=myatoi2(temp); memset(temp,0,10); j=0; m=0; } i++; } if(j!=0) num[k++]=myatoi2(temp); }
void main() { int numarr[4],i; char *arr="abc---897def-67890is9876asd34jmk"; getnum(arr,numarr); for(i=0;i<4;i++) { printf("%d ",numarr[i]); } }
|
5.西南交大2006年840程序题
第2题:返回正整数指定某位数
题目:编写函数Digit(int n,int k),函数返回正整数n左起第k位数,若位数不够返回-1
例如:Digit(31415926,6)=9
Digit(3141,5)=-1
原理:将数字从低位到高位拆分一个一个放进数组,再利用数组下标来定位具体位数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| int Digit(int n,int k) { char ch[10]; int value,index=0; while((value=n%10)!=0) { ch[index]=value; n=n/10; index++; } if(k>index||k==0) { return -1; } return ch[index-k]; }
|
第4题:统计单词
题目:编写程序,从键盘输入一个文本文件名和一个单词,统计在文件中有多少个这样的单词(不区分大小写)
示例:输入:aBc
文件内容(2行):123Abc abc abcd
ABC 7Ashd
输出:2
示例:输入:123aBc
文件内容(2行):123aBc abc 12
3aBC 7Ashd
输出:1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| #include<stdio.h> #include<ctype.h>
void main() { char s[100]; char a[100]; int i=0,j=0; int num=0; FILE *p=fopen("1.txt","r+"); if(p==NULL) { printf("err"); return; } printf("suc\n"); printf("please enter string:"); scanf("%s",a); for(j=0;j<strlen(a);j++) { if(isupper(a[j])) { a[j]+=32; } } printf("\n"); while(!feof(p)) { for(i=0;!feof(p);i++) { char t=fgetc(p); if(t==' '||t=='\t'||t=='\n'||feof(p)) { s[i]='\0'; break; } if(isupper(t)) { t=t+32; } s[i]=t; } if(strcmp(s,a)==0) { num++; } } fclose(p); printf("%d",num); printf("\n"); }
|
第5题:叶子节点数
题目:递归求二叉树叶子结点数
1 2 3 4 5 6 7 8 9
| void Num(BTNode *BT) { if(BT==NULL) return 0; if(BT->left==NULL && BT->right==NULL) return 1; else return Num(BT->left)+Num(BT->right); }
|
6.西南交大2007年840程序题
第1题:迭代求平方根
题目:用迭代法求a的平方根,迭代公式:x[n+1]=(x[n]+a/x[n]),要求前后两次绝对值差小于10的-5次方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include<stdio.h>
void main() { double a,b,x; printf("please enter a number(>0) to get sqrt:"); scanf("%lf",&x); a=1.0; while((fabs(a-b)>1e-5)) { b=a; a=(b+x/b)/2; } printf("the sqrt is:%0.3lf\n",b); }
|
牛顿迭代法:大致就是通过迭代公式求a b,当a b足够接近时b值即为所求平方根
第3题:求素因子乘积
题目:从键盘输入任意一个大于等于2的自然数m,将m写成所有素因子乘积的形式
如:输入:13 输出:13=13
420 420=22357
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include<stdio.h>
void main() { int x,i; printf("please enter a num(>=2):"); scanf("%d",&x); printf("%d=",x); for(i=2;i<=x;i++) { while(x%i==0) { x/=i; if(x==1) { printf("%d",i); break; } printf("%d*",i); } } printf("\n"); }
|
第5题:二叉排序树判断
判断给定二叉树是否为二叉排序树。
王道p191 6
原理:中序遍历看是否递增有序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| KeyType preat=-32767;
int JudgeBST(BiTree bt) { int b1,b2; if(bt==NULL) { return 1; } else { b1=JudgeBST(bt->lchild); if(b1==0 || predt>=bt->data) { return 0; } predt=bt->data; b2=JudgeBST(bt->rchild); return b2; } }
|
7.西南交大2008年840程序题
第4题:求二叉树高度
题目:设计算法求二叉树高度
1 2 3 4 5 6 7 8 9 10 11 12
| int Depth(BiTree &T) { int m,n; if(!T) { return 0; } m=Depth(T->lchild); n=Depth(T->rchild); return (m>n?m:n)+1; }
|
2012 840
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include<stdio.h> #include<string.h>
void main() { char c; char s[100]; int i=0,l=0,h=0; while((c=getchar())!='@') { s[i++]=c; } s[i]='\0'; h=i-1; while(l<h) { if(s[l++]!=s[h--]) { printf("not hui wen\n"); break; } if(l>=h) { printf("hui wen\n"); } } }
|
8.西南交大2013年840程序题
第2题:打印指定字符画
题目:打印如下
到控制台和文件中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #include<stdio.h>
int main() { int n,i,j,l; FILE* file = fopen("test.txt", "w"); printf("输入行数:"); scanf("%d", &n);
for (i = 0; i < n; i++) { for (j = 0; j < n - i; j++) { printf(" "); fwrite(" ", 1, 1, file); } for (l = 0; l < 2 * (i)+1; l++) { printf("*"); fwrite("*", 1, 1, file); } printf("\n"); fwrite("\n", 1, 1, file); } fclose(file); }
|
第3题:为三叉链表存储结构的二叉树指定父节点
题目:编写算法,将所有结点的双亲结点指针域正确填充
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include<stdio.h>
typedef struct node //二叉树采用三叉链表存储 { char ch; struct node* parent; struct node* lchild; struct node* rchild; }TBTNode,*TBTPtr;
void FillParent(TBTPtr root) { TBTNode* temp = root; if(temp==NULL) { return; } if (temp->lchild) { temp->lchild->parent = temp; temp = temp->lchild; FillParent(temp); } if (temp->rchild) { temp->rchild->parent = temp; temp = temp->rchild; FillParent(temp); } }
|
9.西南交大2014年程序题
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include<stdio.h> #include<math.h>
void main() { float i=1,j=1,sum=0,n=pow(10,-6); while(fabs(4*i/j)>=n) { sum+=4*i/j; i*=-1; j+=2; } printf("%.4f",sum); }
|
第2题:打印指定字符画
题目:打印如下
到控制台和文件中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include<stdio.h>
int main() { int n,i,j,l; FILE* file = fopen("test.txt", "w"); printf("输入行数:"); scanf("%d", &n);
for (i = 0; i < n; i++) { for (j = 1; j <=i+1; j++) { printf("%d",j); fprintf(file,"%d",j); } printf("\n"); fprintf(file,"\n"); } fclose(file); }
|
第3题:二叉树中查找指定结点
题目:二叉树中查找指定结点并返回地址,找不到返回NULL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<stdio.h>
typedef struct node { char data; struct node* lchild; struct node* rchild; }BiTNode,*BiTree;
BiTree Locate(BiTree bt, char key) { BiTree p; if (bt == NULL) { return NULL; } else if (bt->data == key) { return bt; } else { p = Locate(bt->lchild, key); if (p) { return p; } else { return Locate(bt->rchild, key); } } }
|
10.西南交大2017年840程序题
第2题:存储学生信息
题目:N个学生,信息有学号、姓名、三门课成绩、三门课平均分。从键盘输入前三个信息,平均分由输入算出,最后将结果存放到文件中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include<stdio.h> #include <malloc.h>
typedef struct Stu { char stuNum[20]; char name[20]; float score[3]; float avg; }Stu;
void main() { int N; FILE* file; file = fopen("test.txt", "w");
printf("学生信息数量:"); scanf("%d", &N);
Stu* stus = (Stu*)malloc(sizeof(Stu) * N); for (int i = 0; i < N; i++) { printf("\n输入%d号学生信息(学号 姓名 三科成绩):", i); scanf("%s %s %f %f %f", stus[i].stuNum, stus[i].name, &stus[i].score[0], &stus[i].score[1], &stus[i].score[2]); stus[i].avg = (stus[i].score[0] + stus[i].score[1] + stus[i].score[2]) / 3;
fprintf(file, " %s %s %f %f %f %f\n", stus[i].stuNum, stus[i].name, stus[i].score[0], stus[i].score[1], stus[i].score[2],stus[i].avg); } fclose(file); }
|
使用fwrite版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include<stdio.h> #include <malloc.h>
typedef struct Stu { char stuNum[20]; char name[20]; float score[3]; float avg; }Stu;
void main() { int N; FILE* file; file = fopen("test.txt", "wb+"); printf("学生信息数量:"); scanf("%d", &N); Stu* stus = (Stu*)malloc(sizeof(Stu) * N); Stu* stus2 = (Stu*)malloc(sizeof(Stu) * N); for (int i = 0; i < N; i++) { printf("\n输入%d号学生信息(学号 姓名 三科成绩):", i); scanf("%s %s %f %f %f", stus[i].stuNum, stus[i].name, &stus[i].score[0], &stus[i].score[1], &stus[i].score[2]); stus[i].avg = (stus[i].score[0] + stus[i].score[1] + stus[i].score[2]) / 3; } fwrite(stus, sizeof(Stu), N, file); rewind(file); fread(stus2, sizeof(Stu), N, file); for (int i = 0; i < N; i++) { printf("%s %s %f %f %f", stus2[i].stuNum, stus2[i].name, stus2[i].score[0], stus2[i].score[1], stus2[i].score[2]); } fclose(file); }
|
11.西南交大2014年959程序题
第10题(填空题):交换二叉树左右子树
题目:交换二叉树左右子树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include<stdio.h>
typedef struct BiTNode { struct BiTNode* lchild, * rchild; int value; }*BiTree,BiTNode;
void Swap(BiTree bt) { if (bt == NULL) { return; } BiTree temp; Swap(bt->lchild); Swap(bt->rchild);
temp = bt->lchild; bt->lchild = bt->rchild; bt->rchild = temp; }
|
第4题:复制二叉树
题目:将以t为树根二叉树复制到以bt为树根中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include<stdio.h> #include<malloc.h>
typedef struct BiTNode { struct BiTNode* lchild, * rchild; int value; }*BiTree, BiTNode;
void Copy(BiTree bt, BiTree& bt2) { if (bt == NULL) { bt2 = NULL; return; } bt2 = (BiTree)malloc(sizeof(BiTNode)); bt2->value = bt->value;
Copy(bt->lchild, bt2->lchild); Copy(bt->rchild, bt2->rchild); }
|
补充:引用,传值区别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include<stdio.h> #include<malloc.h>
void test(int* a) { printf("a_v:%d\n", *a); printf("a:%p\n", a); printf("&a:%p\n\n", &a); }
void test2(int*& b) { printf("b_v:%d\n", *b); printf("b:%p\n", b); printf("&b:%p\n\n", &b); }
void main() { int a = 10; int* p = &a; test(p); test2(p); printf("p_v:%d\n", *p); printf("p:%p\n", p); printf("&p:%p\n\n", &p); }
|
1 2 3 4 5 6 7 8 9 10 11 12
| 输出: a_v:10 a:00F8FA9C &a:00F8F9BC
b_v:10 b:00F8FA9C &b:00F8FA90
p_v:10 p:00F8FA9C &p:00F8FA90
|
显然,bp完全相同。ap只是指向相同,ap俩指针本身地址不同。指针传递本质上也是值传递,只是由于传的是指向地址,所以局部更改能返回到全局
创建二叉树:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include<stdio.h> #include <malloc.h>
typedef struct Node { char data; struct Node* l, * r; }BiNode, * BiTree;
void Create(BiTree &t) { char c = getchar(); if (c != '#') { t = (BiTree)malloc(sizeof(BiNode)); t->data = c; t->l = NULL; t->r = NULL; Create(t->l); Create(t->r); } }
void preOrder(BiTree t) { if (t != NULL) { preOrder(t->l); printf("%c ", t->data); preOrder(t->r); } }
void main() { BiTree t; Create(t); preOrder(t); }
|
位运算
Brian Kernighan(可以用于清除二进制数中最右侧的1)
记 f(x)表示 x 和 x-1 进行与运算所得的结果(即 f(x)=x&(x-1),那么 f(x) 恰为 x 删去(变成0)其二进制表示中最右侧的 1 的结果。
求二进制最后一位
在循环的每一步中,我们可以使用位运算 n & 1 获取 n 的最低位,判断其是否为 1。在这之后,我们将 n 右移一位:n = n >> 1,这样在第 ii 步时,n & 1 得到的就是初始 n 的第 i 个二进制位。
整数转补码:
对于一个正整数x,如果x的类型大小是n位的二进制数,则x的补码为:2的n次方 - x
对于一个负整数x,x的补码为2的n次方+x
找重复子串
给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = “abab”
输出: true
解释: 可由子串 “ab” 重复两次构成。
示例 2:
输入: s = “aba”
输出: false
示例 3:
输入: s = “abcabcabcabc”
输出: true
解释: 可由子串 “abc” 重复四次构成。 (或子串 “abcabc” 重复两次构成。)
解法:我们将两个 ss 连在一起,并移除第一个和最后一个字符。如果 ss 是该字符串的子串,那么 ss 就满足题目要求。
字符串拼接效率问题
引申使用str += “a”, str =str+ “a” 效率差距:
str =str+ “a”加的运算产生的是一个新的对象,再把结果返回,而str += “a” 涉及到的应该是对象的引用,操作之后直接返回引用,避免了产生新的对象。因此,两者的性能有一定的差距。
单调栈
题目只要涉及:求大于某个数的第一个元素、下一个更大元素…这种类似的字眼的,都是单调栈的题目
对于求正因子,记住i*i<num这一条件
最大公因数gcd
1.__gcd在vs内没有,devcpp内有,头文件为#include
附上实现代码:
1 2 3 4 5 6 7 8 9 10
| auto __gcd(auto a, auto b) { auto r = 0; while (a % b != 0) { r = a % b; a = b; b = r; } return b; }
|
2.斐波那契数列最大公约数定理gcd(Fn, Fm) = F(gcd(n, m))
关于C/C++的四舍五入机制
1 2 3 4 5 6
| int main() { printf("%0.1f\n", 0.55); printf("%0.1f\n", 0.54); printf("%d\n", 5 / 2); }
|