--- title: 大作业参考函数 date: 2021-01-05 22:09:31 tags: --- # 第一次大作业 ## 数组逆置与左旋 ```C #include #include #include void Reverse(int* a, int n) { for (int i = 0; i < n / 2; ++i) { int tmp = a[i]; a[i] = a[n - 1 - i]; a[n - 1 - i] = tmp; } } void LeftRotate_1(int* a, int n, int m) { int* b = (int*)malloc(n * sizeof(int)); for (int i = 0; i < m; ++i) { b[n - m + i] = a[i]; } for (int i = m; i < n; ++i) { b[i - m] = a[i]; } memcpy(a, b, n * sizeof(int)); free(b); } void LeftRotate_2(int* a, int n, int m) { Reverse(a, m); Reverse(a + m, n - m); Reverse(a, n); } void LeftRotate_3(int* a, int n, int m) { int max; int min; if (m > n) { max = m; min = n; } else { max = n; min = m; } int t = 1; while (t != 0) { t = max % min; max = min; min = t; } for (int i = 0; i < max; ++i) { int k = i; int oldValue = a[k]; for (int j = 0; j < n / max; ++j) { k = (k + n - m) % n; int newValue = a[k]; a[k] = oldValue; oldValue = newValue; } } } int main() { int a[] = { 1, 2, 3, 4, 5 }; LeftRotate_3(a, 5, 2); for (int i = 0; i < 5; ++i) { printf("%d ", a[i]); } putchar('\n'); return 0; } ``` ## 筛法求素数 ```C #define N 100 void prime(void) { int a1, i, j; int a[N] = { 0 }; char x; int m = 0; printf("请输入想要查找素数范围的上界(不大于%d):\n", N); while (scanf("%d", &a1) != 1) { while ((x = getchar()) != '\n') putchar(x); printf("是无效的命令,重新输入\n"); } if ((a1 <= N) && (a1 >= 2)) { for (i = 1; i < a1; i++) a[i] = i + 1; for (i = 1; i < a1; i++) { if (a[i] != 0) for (j = i + 1; j < a1; j++) if ((a[j] % a[i]) == 0) a[j] = 0; } printf("素数有:\n"); for (i = 0; i < a1; i++) if (a[i] != 0) { m++; printf("%d%c", a[i], m % 5 ? ' ' : '\n'); } } if (a1 <= 1) printf("该区间不存在素数\n"); if (a1 > N) printf("上界溢出\n"); } ``` # 第二次大作业 ## 插入 ```C //字符串连接 char a[N1][N2]; static int b[N1]; int* q = b; char (*p)[N2] = a; int length(int d) //计算字符串长度 { int i = 0; while (*(*(p + d) + i) != '\0') i++; return i; } void insert(int d, int e, int f) //字符串插入 { //d,e是字符串序号,因为可能同时存储着多个字符串,存储使用了二维数组 //f作为作为插入位置,d为主字符串 int i; for (i = (length(d) + length(e) + 1); i > (f + length(e) - 1); i--) *(*(p + d) + i) = *(*(p + d) + i - length(e)); for (i = 0; i < length(e); i++) *(*(p + d) + i + f) = *(*(p + e) + i); } ``` ## 子串与查找 ```C include void SubString(char* s, int pos, int n, char* sub) { int i; for (i = 0; i < n; ++i) { sub[i] = s[pos + i]; } sub[i] = '\0'; } int BeginsWith(char* a, char* b) { for (int i = 0;; ++i) { if (a[i] == b[i]) { if (a[i] == '\0') { return 0; } continue; } if (b[i] == '\0') { return 1; } return 0; } } int Search(char* s, char* t) { for (int i = 0; s[i] != '\0'; ++i) { printf("%s\n%s\n", s + i, t); if (BeginsWith(s + i, t)) { return i; } } return -1; } ``` ## 替换 ```C #include #include #define MAX_LEN 100 void StrReplace(char *s, char *sub, char *new_sub) { // s: 输入的字符串 // sub: 需要替换的子串 // new_sub:替换的新子串 char *p = s, *q; char *s_last = s + strlen(s); // s的结尾'\0'的位置 int sub_len = strlen(sub); int new_sub_len = strlen(new_sub); int diff = new_sub_len - sub_len; // 省略了查找子串的实现,直接调用库函数strstr,找不到子串时返回NULL while (p = strstr(p, sub)) { // 把从p开始的sub字符串替换成new_sub // 首先调整s中这个sub之后的字符的位置 if (diff > 0) { // 如果new_sub比sub长,需要把后面的字符(包括'\0')往后移 for (q = s_last; q >= p + sub_len; q--) { *(q + diff) = *q; } } else if (diff < 0) { // 如果new_sub比sub短,需要把后面的字符(包括'\0')往前移 for (q = p + sub_len; q <= s_last; q++) { *(q + diff) = *q; } } // 把new_sub复制过来 for (q = new_sub; *q != '\0'; q++, p++) { *p = *q; } // 更新s字符串的结尾位置 s_last += diff; } } int main() { char s[MAX_LEN] = "deabcdeafdegdea"; StrReplace(s, "dea", "ii"); printf("%s\n", s); return 0; } ``` # 第三次大作业 ## 打开文件创建链表 ```C #include #include struct Student { char name[10]; float score; struct Student *next; }; struct Student *CreateFromFile(char *filename) { struct Student *temp, *head, *p; FILE *fp; // temp: 新建结点的地址 // head: 链表的头结点地址 // p: 链表最后一个结点的地址 head = (struct Student *)malloc(sizeof(struct Student)); p = head; if (!(fp = fopen(filename, "r"))) { printf("Failed to open file: %s\n", filename); return head; }; temp = (struct Student *)malloc(sizeof(struct Student)); // fscanf读到文件末尾时会返回EOF while (fscanf(fp, "%s %f", temp->name, &temp->score) != EOF) { p->next = temp; p = p->next; temp = (struct Student *)malloc(sizeof(struct Student)); } p->next = NULL; free(temp); fclose(fp); return head; } void Print(struct Student *head) { struct Student *p = head->next; while (p != NULL) { printf("%s %f\n", p->name, p->score); p = p->next; } } int main() { struct Student *head; head = CreateFromFile("test.txt"); Print(head); return 0; } ``` ## 在指定位置插入、有序插入 ```C #include #include typedef struct student { int num; char name[20]; float score; struct student* next; } stu; stu* delete_pos(stu* head, int pos) { /* 删除指定位置记录 :param pos: 指定位置,从0开始 :return head: 返回链表头结点 */ int i; stu *t, *s = head; //链表为空 if (head == NULL) { printf("error: null linked list\n"); } //删除头结点 if (pos == 0) { head = head->next; free(s); return head; } //删除其他节点 for (i = 1; i < pos; i++) { if (s->next == NULL) { printf("error: pos out of range\n"); return head; } s = s->next; } if (s->next == NULL) { printf("error: pos out of range\n"); return head; } t = s->next; s->next = t->next; free(t); return head; } stu* insert_pos(stu* head, stu* s, int pos) { /* 指定位置插入 :param head: 头指针 :param pos: 指定位置,从0开始 :return head: 返回链表头结点 */ stu* t = head; int i; if (i < 0) { printf("error: pos out of range\n"); return head; } //头插 if (pos == 0) { if (head == NULL) { //链表为空 head = s; head->next = NULL; return head; } else { //非空 s->next = head; head = s; return head; } } //其他位置 for (i = 1; i < pos; i++) { if (t->next == NULL) { printf("error: pos out of range\n"); return head; } t = t->next; } s->next = t->next; t->next = s; return head; } stu* insert_order(stu* head, stu* s) { /* 保持有序插入,只考虑正序 :param head: 头指针 :param s: 插入节点 :param pos: 指定位置,从0开始 :return head: 返回链表头结点 */ stu* t = head; int pos = 0; //找到插入位置 while (s->num >= t->num) { if (t->next == NULL) { //链表达到结尾,尾插 pos++; break; } else { t = t->next; pos++; } } return insert_pos(head, s, pos); } ``` ## 删除指定位置、重写学生文件 ```C #include #include #include #define Student struct list struct list { char number[100]; char name[100]; float score; Student* next; }; //利用头结点建立链表,在链表最开头建立一个空白结点 void A_delete(Student* p1) { //删除p1结点的下一个结点 Student* p2 = p1->next; p1->next = p2->next; free(p2); } void A_print(Student* p) { //从p结点开始打印 int n = 1; printf("\n##STUDENT MESSAGE:\n"); while (p != NULL) { printf("No.%d\nSchool Number:%s\nName:%s\nScore:%-5.2f\n\n", n++, p->number, p->.name, p->.score); p = p->next; } } void Delete_pos(Student* head) { Student* p0; int pos, i; A_print((*head).pointer); printf("**MENU/Delete/in certain position**\nPlease input the position(input 0 to break)\n"); scanf("%d", &pos); while (pos) { p0 = head; for (i = 1; ((i < pos) && (p0->next != NULL)); i++) p0 = p0->next; A_delete(p0); A_print(head->next); printf("Please input a position(input 0 to break)\n"); scanf("%d", &pos); } } void Record_write(Student* head, char* a) { //a用于不同的功能,当a为‘w’代表重写,当a为'a'代表追加 FILE* f; char filename[100]; Student* p = head->next; printf("**MENU/Record**\n"); printf("Please input the file name\n"); gets(filename); f = fopen(filename, a); while (p != NULL) { fputs(p->number, f); fprintf(f, "\n"); fputs(p->name, f); fprintf(f, "\n"); fprintf(f, "%-5.2f\n", p->score); p = p->next; } fclose(f); printf("Write OK!\n"); } ``` ## 追加学生文件、清空学生文件 ```C #include #include #include struct student { int id; char name[20]; int score; struct student *next; }; void append_file(struct student *head, char *file_path) { struct student *p; FILE *fp; if (head == NULL) { return; } fp = fopen(file_path, "a"); if (fp == NULL) { printf("open file %s failed", file_path); return; } p = head; // head 是第一个节点 // p=head->next; // 如果 head 是专门的头节点,用这种写法 while (p != NULL) { fprintf(fp, "%d %s %d\n", p->id, p->name, p->score); p = p->next; } fclose(fp); } void clear_file(char *file_path) { FILE *fp = fopen(file_path, "w"); if (fp == NULL) { printf("open file %s failed", file_path); return; } fclose(fp); } int main() { struct student *head, *p; char file_path1[] = "stu1.txt"; char file_path2[] = "stu2.txt"; head = malloc(sizeof(struct student)); head->id = 0; strcpy(head->name, "stu0"); head->score = 90; head->next = NULL; p = malloc(sizeof(struct student)); p->id = 1; strcpy(p->name, "stu1"); p->score = 89; p->next = NULL; head->next = p; append_file(head, file_path1); append_file(head, file_path1); append_file(head, file_path2); clear_file(file_path2); return 0; } ```