iOS 逆向开发工具_数组

字符串反转

给定字符串“hello,world”,实现将其反转,输出结果:dlrow,olleh

iOS 逆向开发工具_链表_02


定义两个指针,begin和end,begin++,end–,所指元素交换,当begin>=end,程序结束

@interface CharReverse : NSObject
void charReverse(char *);
@end

#import "CharReverse.h"
@implementation CharReverse
void charReverse(char *cha)
{
    char *begin = cha;
    char *end = cha + strlen(cha) - 1;
    
    while (begin < end) {
        char temp = *begin;
        *begin = *end;
        *end = temp;
        
        begin++;
        end--;
    }
}
@end

- (void)viewDidLoad {
    [super viewDidLoad];
    
    char cha[] = "hello,world";
    charReverse(cha);
    printf("%s", cha);
}

结果:
dlrow,olleh

链表反转

iOS 逆向开发工具_链表_03

iOS 逆向开发工具_#import_04


iOS 逆向开发工具_iOS 逆向开发工具_05


定义一个新的结点NewH,其结点的next指针为NULL,NewH->pNext = NULL;

定义一个临时结点temp和p,都指向第一个结点p = Head->next

然后,p向下移动一个位置,p = p->pNext;

将temp->next = NewH->next;

NewHead->next = tempNode;

tempNode = pNode;

#import <Foundation/Foundation.h>
struct Node{
    int data;
    struct Node *next;
};
@interface ReverseList : NSObject
//创建一个链表
struct Node *createList(void);

//反转链表
struct Node *reverseList(struct Node * head);

//打印一个链表
void printReverseList(struct Node * head);
@end



#import "ReverseList.h"

@implementation ReverseList
//创建一个链表
struct Node *createList(void)
{
    //头指针=头结点
    struct Node *head = (struct Node *)malloc(sizeof(struct Node));
    head->next = NULL;
    
    //tailNode指向最后一个节点
    struct Node *tailNode = head;
    
    for (int i = 1; i<5; i++) {
        struct Node *node = (struct Node *)malloc(sizeof(struct Node));
        node->data = i;
        node->next = NULL;
        
        tailNode->next = node;
        tailNode = node;
    }
    
    return head;
}

//反转链表
struct Node *reverseList(struct Node * head)
{
    //新建一个头结点
    struct Node *NewHead = (struct Node *)malloc(sizeof(struct Node));
    NewHead->next = NULL;
    
    struct Node *tempNode = head->next;
    struct Node *pNode = tempNode;
    
    while (pNode != NULL) {
        pNode = tempNode->next;
        tempNode->next = NewHead->next;
        NewHead->next = tempNode;
        tempNode = pNode;
    }
    return NewHead;
}

//打印一个链表
void printReverseList(struct Node * head)
{
    struct Node *temp = head->next;
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp -> next;
    };
}
@end


调用:
- (void)viewDidLoad {
    [super viewDidLoad];
	struct Node *head =  createList();
	printReverseList(head);
	struct Node *NewHead = reverseList(head);
	printReverseList(NewHead);
}

上述代码是自己写出来的,跟老师讲的不一样
用自己写的代码放入到leetcode执行有问题,这真的是。。。
贴上老师的代码

struct Node* reverseList(struct Node *head)
{
    // 定义遍历指针,初始化为头结点
    struct Node *p = head;
    // 反转后的链表头部
    struct Node *newH = NULL;
    
    // 遍历链表
    while (p != NULL) {
        
        // 记录下一个结点
        struct Node *temp = p->next;
        // 当前结点的next指向新链表头部
        p->next = newH;
        // 更改新链表头部为当前结点
        newH = p;
        // 移动p指针
        p = temp;
    }
    
    // 返回反转后的链表头结点
    return newH;
}

有序数组合并

iOS 逆向开发工具_链表_06


两个有序数组:

1 4 6 7 9

2 3 5 6 8 10 11 12

合并成一个新的有序数组

1 2 3 4 5 6 6 7 8 9 10 11 12

iOS 逆向开发工具_iOS 逆向开发工具_07

iOS 逆向开发工具_数组_08

定义两个指针,分别指向两个数组第一个元素,比较其大小,谁小将谁的元素放进新的数组,并将指针++操作。
直至p或者q为空,将剩余的另一数组元素遍历放进新数组。

@interface MergeSortedList : NSObject
void mergeSortedList(int a[], int aLen, int b[], int bLen, int result[]);
@end

#import "MergeSortedList.h"

@implementation MergeSortedList
void mergeSortedList(int a[], int aLen, int b[], int bLen, int result[])
{
    int p = 0;
    int q = 0;
    int i = 0;//reslut数组当前位置
    
    while (p < aLen && q<bLen) {
        if (a[p] > b[q]) {
            result[i] = b[q];
            i++;
            q++;
        }else if (a[p] <= b[q]) {
            result[i] = a[p];
            i++;
            p++;
        }
    }
    
    //a数组有剩余
    while (p < aLen) {
        result[i] = a[p];
        p++;
        i++;
    }
    
    //b数组有剩余
    while (q < bLen) {
        result[i] = b[q];
        q++;
        i++;
    }
    
}
@end

- (void)viewDidLoad {
    [super viewDidLoad];
    
    int a[] = {1, 4, 6, 7, 9};
    int b[] = {2, 3, 5, 6, 8, 10, 11, 12};
    int reslut[13];
    mergeSortedList(a, 5, b, 8, reslut);
    
    for (int i = 0; i<13; i++) {
        printf("%d ", reslut[i]);
    }
}

打印结果:
1 2 3 4 5 6 6 7 8 9 10 11 12

Hash算法

一般不是问你Hash算法的具体原理,而是通过一个例子让你做,例子用到的算法是Hash算法

在一个字符串中找到第一个只出现一次的字符
比如:输入“abaccdeff”,则输出b

算法思路

字符(char)占1个字节,8位,可以表达2^8 = 256种不同的表示

建立一个数组
数组中存储的元素,是每个字符出现的次数
每个字母,都有一个ASCII码值,可以让ASCII码值作为数组的下标
这样,字符和数组出现次数建立了联系

字符a
array[a的ASCII] = a出现的次数;

比如:
给定的字符是a,a对应的ASCII值是97,那么数组下标为97
array[97] = a出现的次数;

Hash存储与查找是用的同一个Hash函数,这样,查找的时候才能快速查找。

@interface HashFind : NSObject

// 查找第一个只出现一次的字符
char findFirstChar(char* cha);

@end

#import "HashFind.h"

@implementation HashFind

char findFirstChar(char* cha)
{
    // 定义一个数组 用来存储各个字母出现次数
    int array[256];
    // 对数组进行初始化操作
    for (int i=0; i<256; i++) {
        array[i] =0;
    }
    // 定义一个指针 指向当前字符串头部
    char* p = cha;
    // 遍历每个字符
    while (*p != '\0') {
        // 在字母对应存储位置 进行出现次数+1操作
        array[*(p++)]++;
    }
    
    // 将P指针重新指向字符串头部
    p = cha;
    
    char result = '\0';
    
    // 遍历每个字母的出现次数
    while (*p != '\0') {
        // 遇到第一个出现次数为1的字符,打印结果
        if (array[*p] == 1)
        {
            result = *p;
            break;
        }
        // 反之继续向后遍历
        p++;
    }
    
    return result;
}

@end

调用:
- (void)viewDidLoad {
    [super viewDidLoad];
    
    char cha[] = "a, a, a, c, c, d, d, e, g, e, f, f";
    char cha1 = findFirstChar(cha);
    printf("%c", cha1);
}

打印结果:
g

查找两个子视图的共同父视图

iOS 逆向开发工具_数组_09


将ViewA的所有父视图放在一个数组A里面

将ViewB的所有父视图放在一个数组B里面

从数组右边,对比两个数组元素是否一样,一样,则都–,直至找到第一个不一样的地方,则,之前的所有元素都是两个View的共同父视图。

老师上课讲的方法:

#import <UIKit/UIKit.h>
@interface CommonSuperFind : NSObject

// 查找两个视图的共同父视图
- (NSArray<UIView *> *)findCommonSuperView:(UIView *)view other:(UIView *)viewOther;

@end

#import "CommonSuperFind.h"

@implementation CommonSuperFind

- (NSArray <UIView *> *)findCommonSuperView:(UIView *)viewOne other:(UIView *)viewOther
{
    NSMutableArray *result = [NSMutableArray array];
    
    // 查找第一个视图的所有父视图
    NSArray *arrayOne = [self findSuperViews:viewOne];
    // 查找第二个视图的所有父视图
    NSArray *arrayOther = [self findSuperViews:viewOther];
    
    int i = 0;
    // 越界限制条件
    while (i < MIN((int)arrayOne.count, (int)arrayOther.count)) {
        // 倒序方式获取各个视图的父视图
        UIView *superOne = [arrayOne objectAtIndex:arrayOne.count - i - 1];
        UIView *superOther = [arrayOther objectAtIndex:arrayOther.count - i - 1];
        
        // 比较如果相等 则为共同父视图
        if (superOne == superOther) {
            [result addObject:superOne];
            i++;
        }
        // 如果不相等,则结束遍历
        else{
            break;
        }
    }
    
    return result;
}

- (NSArray <UIView *> *)findSuperViews:(UIView *)view
{
    // 初始化为第一父视图
    UIView *temp = view.superview;
    // 保存结果的数组
    NSMutableArray *result = [NSMutableArray array];
    while (temp) {
        [result addObject:temp];
        // 顺着superview指针一直向上查找
        temp = temp.superview;
    }
    return result;
}


@end

自己想的方法:

@interface CommonSuperFind : NSObject
- (NSArray *)findCommonSuperView:(UIView *)view other:(UIView *)otherView;
@end

#import "CommonSuperFind.h"

@implementation CommonSuperFind
- (NSArray *)findCommonSuperView:(UIView *)view other:(UIView *)otherView
{
    NSMutableArray *arrayA = [NSMutableArray array];
    NSMutableArray *arrayB = [NSMutableArray array];
    NSMutableArray *arrayC = [NSMutableArray array];

    while (view.superview != nil) {
        [arrayA addObject:view.superview];
        view = view.superview;
    }
    
    while (otherView.superview != nil) {
        [arrayB addObject:otherView.superview];
        otherView = otherView.superview;
    }
    
    while (arrayA.lastObject == arrayB.lastObject && arrayA.count && arrayB.count) {
        [arrayC addObject:arrayA.lastObject];
        [arrayA removeLastObject];
        [arrayB removeLastObject];
    }
    
    return arrayC;
    
}
@end

我觉得我这个方法也挺好的,大家觉得有问题的话,请随时指正


求无序数组当中的中位数

方法一:利用排序算法,将数组排序,然后找到中间数
方法二:利用快排思想查找中位数(分治思想)

iOS 逆向开发工具_链表_10

iOS 逆向开发工具_链表_11

@interface MiddleFind : NSObject
int findMiddle(int a[], int aLen);
@end


#import "MiddleFind.h"

@implementation MiddleFind

int quickSort(int a[], int low, int high);

int findMiddle(int a[], int aLen)
{
    int middle1 = (aLen - 1)/2;
    
    int middle2 = quickSort(a, 0, aLen - 1);
    
    while (middle1 != middle2) {
        if (middle1 < middle2) {
            middle2 = quickSort(a, 0, middle2 - 1);
        }else{
            middle2 = quickSort(a, middle2+1, aLen - 1);
        }
        
    }
    return a[middle1];
}

int quickSort(int a[], int low, int high)
{
    int i = low;
    int j = high;
    int temp = a[i];
    
    if (low < high) {
        while (i < j) {
            while (a[j] >= temp && (i<j)) {
                j--;
            }
            a[i] = a[j];
            
            while ((a[i] <= temp) && (i<j)) {
                i++;
            }
            a[j] = a[i];
        }
    }
    a[i] = temp;
    return i;
}
@end

调用
- (void)viewDidLoad {
    [super viewDidLoad];
    int a[] = {12,3,10,8,6,7,11,13,9};
    int result = findMiddle(a, 9);
}

结果:
9