• 算法练习字符翻转


    练习问题来源

    https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/01.01.html

    要求:

    给 定一个字符串,要求把字符串前面的若干个字符移动到字符串的尾部,如把字符串“abcdef”前面的2个字符'a'和'b'移动到字符串的尾部,使得原 字符串变成字符串“cdefab”。请写一个函数完成此功能,要求对长度为n的字符串操作的时间复杂度为 O(n),空间复杂度为 O(1)。

    解法:三步反转法

    #include <stdio.h>
    #include <stdlib.h>
    
    // 把字符一个一个地移动到字符串的尾部
    /*void LeftShiftOne(char* s, int n)
    {
        char t = s[0];
        for (int i = 1; i < n; i++)
        {
            s[i-1] = s[i];
        }
        s[n-1] = t;
    }

    void LeftRotateString(char* s, int n, int m)
    {
        while(m--)
        {
            LeftShiftOne(s, n);
        }
    }*/ // 例如,字符串 abcdef ,若要让def翻转到abc的前头,只要按照下述3个步骤操作即可: // 1. 首先将原字符串分为两个部分,即X:abc,Y:def; // 2. 将X反转,X->X^T,即得:abc->cba;将Y反转,Y->Y^T,即得:def->fed。 // 3. 反转上述步骤得到的结果字符串X^TY^T,即反转字符串cbafed的两部分(cba和fed)给予反转, // cbafed得到defabc,形式化表示为(X^TY^T)^T=YX,这就实现了整个反转。 void ReverseString(char* s, int from, int to) { char t; while(from < to) { t = s[from]; s[from++] = s[to]; s[to--] = t; } } void LeftRotateString(char* s, int n, int m) // 字符串长度 n, 翻转前 m 个 { m %= n; //若要左移动大于n位,那么和%n 是等价的 ReverseString(s, 0, m-1); ReverseString(s, m, n-1); ReverseString(s, 0, n-1); } void main() { char s[7] = {'s', 't', 'u', 'i', '4', '5', 'm'}; for (int i=0; i<7; i++) { printf("%c ", s[i]); } printf("\n"); LeftRotateString(s, 7, 4); for (int i=0; i<7; i++) { printf("%c ", s[i]); } }

     

    相关练习

    链表翻转。给出一个链表和一个数k,比如,链表为1→2→3→4→5→6,k=2,则翻转后2→1→6→5→4→3,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→6→5。

    /* List.h */
    #ifndef _List_H
    #define _List_H
    
    struct Node;
    typedef struct Node *PtrToNode;
    typedef PtrToNode List;
    typedef PtrToNode Position;
    typedef int ElementType;
    
    List MakeEmpty(List L);
    int IsEmpty(List L);
    int IsLast(Position P, List L);
    Position Find(ElementType X, List L);
    void Delete(ElementType X, List L);
    Position FindPrevious(ElementType X, List L);
    void Insert(ElementType X, List L, Position P);
    void DeletList(List L);
    
    struct Node
    {
        ElementType Element;
        Position Next;
    };
    
    #endif
    List.h
    /* List.cpp */
    #include "List.h"
    #include <stdlib.h>
    #include <stdio.h>
    
    // Return true if L is empty, 测试链表是否为空表
    int IsEmpty(List L)
    {
        return L->Next == NULL;
    }
    
    // Return true if P is the last position in list L
    // Parameter L is unused in this implementation
    // 测试当前位置是否是链表末尾
    int IsLast(Position P, List L)
    {
        return P->Next == NULL;
    }
    
    // Return Position of X in L; NULL if not found
    Position Find(ElementType X, List L)
    {
        Position P;
        P = L->Next;
        while(P != NULL && P->Element != X)
            P = P->Next;
    
        return P;
    }
    
    void Delete(ElementType X, List L)
    {
        Position P, TmpCell;
    
        P = FindPrevious(X, L);
    
        if (!IsLast(P, L))
        {
            TmpCell = P->Next;
            P->Next = TmpCell->Next;  //P->Next->Next;
            free(TmpCell);
        }
    }
    Position FindPrevious(ElementType X, List L)
    {
        Position P;
    
        P = L;
        while(P->Next != NULL && P->Next->Element != X)
            P = P->Next;
    
        return P;
    }
    
    // Insert (after legal position)
    // Header implementation assumed
    // Parameter L is unused in this implementation
    void Insert(ElementType X, List L, Position P)
    {
        Position TmpCell;
    
        TmpCell = (struct Node*)malloc(sizeof(struct Node));
        if (TmpCell == NULL)
            printf("Fatal Error: Out of space!!");
    
        TmpCell->Element = X;
        TmpCell->Next = P->Next;
        P->Next = TmpCell;
    }
    
    void DeleteList(List L)
    {
        Position P, Tmp;
    
        P = L->Next;
        L->Next = NULL; // Header assumed
        while(P != NULL)
        {
            Tmp = P->Next;
            free(P);
            P = Tmp;
        }
    }
    List.cpp
    #include <stdio.h>
    #include <stdlib.h>
    #include "List.h"
    // 链表翻转:
    // 给出一个链表和一个数k,比如,链表为1→2→3→4→5→6,k=2,则翻转后2→1→6→5→4→3,
    // 若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→6→5
    void ListReverseFunc(List L, int k, int m)
    {
        while (k < m)
        {
            int ikPos = 1;
            int imPos = 1;
            Position pkPos, pmPos;
            pkPos = L->Next;
            pmPos = L->Next;
            while(ikPos < k)
            {
                pkPos = pkPos->Next;
                ikPos++;
            }
            while(imPos < m)
            {
                pmPos = pmPos->Next;
                imPos++;
            }
            // 交换 k, m 位置的值
            pkPos->Element = pkPos->Element + pmPos->Element;
            pmPos->Element = pkPos->Element - pmPos->Element;
            pkPos->Element = pkPos->Element - pmPos->Element;
    
            k++;
            m--;
        }
    }
    
    void main()
    {
        // 定义一个链表 ListReverse
        typedef PtrToNode List;
        List ListReverse;
        ListReverse = (struct Node*)malloc(sizeof(struct Node));
    
        // 对链表赋值 1, 2,..., 7
        Position P = ListReverse;
        for (int i = 1; i < 8; ++i)
        {
            P->Next = (struct Node*)malloc(sizeof(struct Node));
            Insert(i, ListReverse, P);
            P = P->Next;
        }
        P->Next = NULL; // 赋值结束, 链表尾部, 置空
    
        // k = 3, 反转链表
        int k = 5;
        ListReverseFunc(ListReverse, 1, k);
        ListReverseFunc(ListReverse, k+1, 7);
    
        // 输出翻转结果
        P = ListReverse->Next;
        while(!IsLast(P, ListReverse))
        {
            printf("%d, ", P->Element);
            P = P->Next;
        }
        printf("%d\n", P->Element);
      
        DeleteList(ListReverse); }

  • 相关阅读:
    WPF treeview 多层次绑定问题 HierarchicalDataTemplate 和 CompositeCollection
    Difference between Visibility.Collapsed and Visibility.Hidden
    WPF style的继承
    Asp.net个性化服务《系列03_购物车》
    SQLServer2005中的uniqueidentifier数据类型与NEWID()函数
    扉页语
    Asp.net个性化服务《系列01_概述》
    Asp.net个性化服务《系列02_快速的匿名用户个性化》
    2010年java课程体系
    easyui修改提示窗
  • 原文地址:https://www.cnblogs.com/nobodyzhou/p/5459227.html
Copyright © 2020-2023  润新知