使用穷举法计算24点

     24点游戏是一种益智游戏,24点是把4个整数(一般是正整数)通过加减乘除以及括号运算,使最后的计算结果是24的一个数学游戏. 平时我也经常这样玩这个游戏,经常是在算出一个结果之后就结束了,后来就在想, 有的题目结果只有一个 ,但是大部分的结果通常是不止一个, 怎么列出所有的解呢, 在用脑子算 肯定是不全的 , 那就试试穷举法吧. 

     穷举法,思路上比较简单,
先把所有可能的数字组合列出来, 4*3*2*1总共有24种, 
在处理符号的, 由于符号有优先级和括号,如果考虑括号的情况就比较多了,没有括号,1个括号,2个括号的情况.所以就不太想处理括号,所以对所有的符号进行全排列,然后按照排列顺序处理,不考虑符号间的优先级. 加减乘除,总共需要3个符号, 4*4*4有64种组合.
当然这是最初的想法, 回来在写测试用例的时候,发现了一种情况6,11,10,12 , 这种只有10/(11-6)*12, 这种必须有括号, 但是我又不想加括号, 就又加入了一种符号, 注意了10除以5是10/5 , 但是10除5 是5/10, 有了这种符号就可以处理这种情况了. 所以符号的全排列是 5*5*5=125种,
现在用24种数组组合和125种符号组合,相互叠加处理, 算出来的就是所有可能的解了.

还有一个, 用oc简单的封装了一个栈的数据结构

#import <Foundation/Foundation.h>

@interface Stack : NSObject<NSCopying>

@property (nonatomic,readonly,assign) NSUInteger count ;
- (void)push:(id)obj;
- (id)pop;
@end

------------------------

#import "Stack.h"

@interface Stack ()

@property (nonatomic,strong) NSMutableArray * array ;

@end

@implementation Stack

- (NSUInteger)count {
    return self.array.count;
}

- (void)push:(id)obj {
    [self.array addObject:obj];
}
- (id)pop {
    id obj = self.array.lastObject ;
    [self.array removeLastObject];
    return obj;
}


- (NSMutableArray *)array {
    if (_array == nil) {
        _array = [NSMutableArray array];
    }
    return _array;
}

- (NSString *)description {
    NSMutableString * str = [[NSMutableString alloc] init];
    for (int i = self.array.count-1; i>=0; i--) {
        [str appendFormat:@"%@ ", self.array[i]];
    }
    return str;
}
- (id)copyWithZone:(nullable NSZone *)zone {
    Stack * newStack = [Stack new];
    newStack.array = [self.array mutableCopy];
    return newStack;
}


@end

算法的主体部分

#import "ViewController.h"
#import "Stack.h"

@interface ViewController ()

@property (nonatomic,strong) NSMutableArray * resultArray ;

@end


@implementation ViewController

- (void)test {
    
    //    int a[4] = {6,11,10,12};
    int a[4] = {3,4,5,5};

    NSArray * nums = [self getNums:a];
    for (int i = 0; i<nums.count; i++) {
        Stack * numStack = nums[i];
        NSArray * symbolArray = [self getSymbol];
        for (int j = 0; j<symbolArray.count; j++) {
            Stack * symbolStack = symbolArray[j];
            [self jiSuan:numStack withSymbolStack:symbolStack];
        }
        
    }
    
    NSLog(@"%@",self.resultArray);
    
}

- (double)jiSuan:(Stack *)numStack withSymbolStack:(Stack *)symbolStack {
    
    Stack * nums = [numStack copy];
    Stack * symbols = [symbolStack copy];

    while (nums.count>1) {
        double firstNum = [[nums pop] doubleValue];
        double secondtNum = [[nums pop] doubleValue];
        
        NSString * symbol = [symbols pop];
        
        if ([symbol isEqualToString:@"+"]) {
            [nums push:@(firstNum + secondtNum)];
        } else if ([symbol isEqualToString:@"-"]){
            [nums push:@(firstNum - secondtNum)];
        } else if ([symbol isEqualToString:@"*"]){
            [nums push:@(firstNum * secondtNum)];
        } else if ([symbol isEqualToString:@"/"]){
            [nums push:@(firstNum / secondtNum)];
        } else if ([symbol isEqualToString:@"#"]){
            [nums push:@(secondtNum / firstNum)];
        }
        
    }
    
    
    double result = [[nums pop] doubleValue];
    NSLog(@"%@ %@ = %@",numStack,symbolStack,@(result));
    
    if (result == 24) {
        [self.resultArray addObject:[NSString stringWithFormat:@"%@ %@",numStack,symbolStack]];
    }
    
    return result;
}



/// 返回数字的全排列
- (NSArray *)getNums:(int *)a{
    
    NSMutableArray * result = [NSMutableArray array];
    for (int i=0; i<4; i++) {
        for (int j=0; j<4; j++) {
            
            if (i==j) {
                continue;
            }
            
            for (int k = 0; k<4; k++) {
                
                if (j==k || i==k) {
                    continue;
                }
                
                for (int m=0; m<4; m++) {
                    if (k==m || i==m | j==m) {
                        continue;
                    }
                    
                    // 如果i,j,k,m4个数字各不相等,说明是一种组合,记录下来
                    NSLog(@"%d %d %d %d",a[i],a[j],a[k],a[m]);
                    Stack * stack = [Stack new];
                    [stack push:@(a[i])];
                    [stack push:@(a[j])];
                    [stack push:@(a[k])];
                    [stack push:@(a[m])];
                    [result addObject:stack];
                }
                
                
            }
            
        }
        
    }
    
    
    return result;
}

/// 获取符号的全排列
- (NSArray *)getSymbol {
    NSMutableArray * result = [NSMutableArray array];
    // 加减乘除,最后一个是取倒数相乘
    NSArray * array = @[@"+",@"-",@"*",@"/",@"#"];

    for (int i=0; i<array.count; i++) {
        for (int j=0; j<array.count; j++) {
            
            for (int k = 0; k<array.count; k++) {
                
                
                NSLog(@"%@ %@ %@",array[i],array[j],array[k]);
                Stack * stack = [Stack new];
                [stack push:array[i]];
                [stack push:array[j]];
                [stack push:array[k]];
                [result addObject:stack];
                 
            }
            
        }
        
    }
    
    return result;
}

- (NSMutableArray *)resultArray {
    if (_resultArray == nil) {
        _resultArray = [NSMutableArray array];
    }
    return _resultArray;
}

@end
发布了101 篇原创文章 · 获赞 33 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/u014600626/article/details/104938909