iPhone最長部分増加列

最長増加部分列をパラパラめくりで表示してみようと試みた。。。iPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#include <memory>

#include <algorithm>

#define MAXN 100

#define INF 10000

using namespace std;

class LISSolver {

public:

    int lastNumber;

    int size;

    int dp[MAXN];

    void solve(NSArray*);

};

void LISSolver::solve(NSArray *arr) {

    if (!arr) {

        return;

    }

    

    int n = (int)arr.count;

    

    fill(dp, dp + MAXN, INF);

    for (NSNumber *a in arr) {

        *lower_bound(dp, dp + n, [a intValue]) = [a intValue];

    }

    

    size = (int)(lower_bound(dp, dp + n, INF) – dp);

    lastNumber = dp[size1];

};

@interface ViewController ()

@property (nonatomic, strong) NSMutableArray *numbers;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    

    self.view.backgroundColor = [UIColor colorWithHue:0.25 saturation:1 brightness:0.3 alpha:1];

    

    UILabel *title = [[UILabel alloc] init];

    title.font = [UIFont systemFontOfSize:22];

    title.textColor = [UIColor whiteColor];

    title.text = @”Longest Increasing Subsequence”;

    [title sizeToFit];

    title.center = CGPointMake(CGRectGetMidX(self.view.bounds), 70);

    [self.view addSubview:title];

    

    

    self.numbers = [NSMutableArray array];

    

    for (int i=0; i<64; i++) {

        int number = arc4random() % 100 + 1;

        [self.numbers addObject:@(number)];

        

        float x = ((i % 8) + 1) * CGRectGetMaxX(self.view.bounds) / 10;

        float y = (i / 8) * CGRectGetMaxX(self.view.bounds) / 10 + 100;

        

        UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 30, 30)];

        l.tag = number;

        l.text = [NSString stringWithFormat:@”%d”, number];

        l.textAlignment = NSTextAlignmentCenter;

        l.backgroundColor = [UIColor colorWithHue:0.1 * (i % 10) saturation:0.2 brightness:1 alpha:1];

        [self.view addSubview:l];

    }

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    shared_ptr<LISSolver> cppClass(new LISSolver());

    cppClass->solve(self.numbers);

    

    // calc

    int last = cppClass->lastNumber;

    

    

    // for animation …..

    NSArray *numberLabelArr = [self.view.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@”tag > 0″]];

    for (int i=0; i<numberLabelArr.count; i++) {

        int idx = (int)numberLabelArr.count – i – 1;

        UIView *v = numberLabelArr[idx];

        if (v.tag > 0) {

            if (v.tag == last) {

                if (idx > 1) {

                    NSArray *subArr = [self.numbers subarrayWithRange:NSMakeRange(0, idx)];

                    subArr = [subArr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@”self < %d”, last]];

                    cppClass->solve(subArr);

                    last = cppClass->lastNumber;

                }

                continue;

            }

            [UIView animateWithDuration:0.2 delay:i * 0.1  options:0 animations:^{

                v.layer.transform = CATransform3DMakeRotation(M_PI * 0.5, 0, 1, 0);

            } completion:nil];

        }

    }

}

@end