C_TA_Website/source/_posts/big-functions.md

12 KiB

title date tags
大作业参考函数 2021-01-05 22:09:31

第一次大作业

数组逆置与左旋

#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;
}

筛法求素数

#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");
}

第二次大作业

插入

//字符串连接
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);
}

子串与查找

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;
}

替换

#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;
}

第三次大作业

打开文件创建链表

#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);
    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;
}

在指定位置插入、有序插入

#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);
}

删除指定位置、重写学生文件

#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");
}

追加学生文件、清空学生文件

#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;
}