c语言 链式串中子串的替换算法怎么写

若采用单链存储的方式存储串,编写一个算法将串s中的第i个字符到第
j个字符之间的字符(不包括i和j)用t串替换

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    char data;
    struct Node* next;
} Node, *LinkedList;

// 创建一个空链表
LinkedList createList() {
    LinkedList L = (LinkedList)malloc(sizeof(Node));
    L->next = NULL;
    return L;
}

// 将一个字符串转换为单链表
LinkedList stringToList(char s[]) {
    LinkedList L = createList();
    Node* tail = L;
    for (int i = 0; s[i] != '\0'; i++) {
        Node* p = (Node*)malloc(sizeof(Node));
        p->data = s[i];
        p->next = NULL;
        tail->next = p;
        tail = p;
    }
    return L;
}

// 将链表转换为一个字符串
void listToString(LinkedList L, char s[]) {
    int i = 0;
    Node* p = L->next;
    while (p != NULL) {
        s[i++] = p->data;
        p = p->next;
    }
    s[i] = '\0';
}

// 将s串中第i个字符到第j个字符之间的字符(不包括i和j)用t串替换
void replaceSubString(LinkedList L, int i, int j, char t[]) {
    // 找到第i个节点前面的节点
    Node* p = L;
    for (int k = 1; k < i; k++) {
        if (p == NULL) {
            printf("i太大\n");
            return;
        }
        p = p->next;
    }
    // 找到第j个节点
    Node* q = p;
    for (int k = i; k <= j; k++) {
        if (q == NULL) {
            printf("j太大\n");
            return;
        }
        q = q->next;
    }
    // 将[t]插入到p和q之间
    Node* tList = stringToList(t);
    Node* tail = tList;
    while (tail->next != NULL) {
        tail = tail->next;
    }
    tail->next = q;
    p->next = tList->next;
    free(tList);
}

int main() {
    char s[] = "Hello, world!";
    LinkedList L = stringToList(s);

    printf("原始串:\n");
    printf("%s\n", s);

    replaceSubString(L, 7, 12, "GitHub");
    char s2[20];
    listToString(L, s2);

    printf("替换后的串:\n");
    printf("%s\n", s2);

    return 0;
}

  • 这篇博客: 如何快速理解最大流和最小割中的 1.1思考这样一个问题:在给定的图中,如何判断一个源点s到终点t是否有路径存在呢? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 我们首先想到的是用BFS或者是DFS算法对图进行遍历,如果可以返回一条从源点s到终点t的路径,那么就说明在图中是存在从s到t的路径的。但是如何证明当DFS或者BFS返回不了这样一条路径的时候,就不存在s到t的路径了呢?这证明起来就有点困难。
    我们不妨这样想:
    将所有的可能的s到t的路径全部都列出来:
    如:
    s,a,t
    s,a,b,t
    s,a,b,c,t
    那么对于每一条可能的路径,如果这条路径存在,那么就说明路径中相邻节点对应的边肯定在图中是存在的。由此可以严格的证明图中是否存在s到t的路径。
    方法的缺点:
    但是这种方法对于节点比较少的时候还是可以的,对于节点比较多的图,显然没有可行性,比如,有一个1000个节点的中等大小的图,那么可能的路径就有至少2^998以上条,显然数据量太大了。
    割集的诞生
    上述方法不是普遍高效的方法,因此行不通。我们不妨这样想:
    如果我把整个图中节点分成两个部分,一部分是源点s所在的集合S,一部分是终点t所在的集合T。
    对于一条从s到t的路径,肯定要存在一对相邻的节点(u,v),其中u在S中,而v在T中。那么这两点所在的边肯定会从S中穿过集合的边界,到达T中,我们称这样的一个集合分布为图的一个割。
    那么上面的路径存在问题就可以描述为,不存在从集合S到集合T的一个割,也就是集合S到T的路径条数为零!
    bingo!!!第一个有关割的结论出来了:
    若从S到T的路径为零,则不存在s到t的路径,其中s∈S,t∈T。
    好,下面我们把路径存在问题升级。