2021-01-06 00:35:47 +08:00
|
|
|
---
|
|
|
|
title: 大作业参考函数
|
|
|
|
date: 2021-01-05 22:09:31
|
|
|
|
tags:
|
|
|
|
---
|
|
|
|
|
|
|
|
# 第一次大作业
|
|
|
|
|
|
|
|
## 数组逆置与左旋
|
|
|
|
|
|
|
|
```C
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
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 <stdio.h>
|
|
|
|
|
|
|
|
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 <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#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 <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
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);
|
2021-01-06 16:35:42 +08:00
|
|
|
fclose(fp);
|
2021-01-06 00:35:47 +08:00
|
|
|
|
|
|
|
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 <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
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 <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#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 <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
```
|