实现不同范围集合之间操作

1,集合范围

Q={x|x属于z,x<=2*32-1}
(a-b)={x|x,a,b属于Q,a<=x<=b}
(a,b,c)={x|x,a,b,c属于Q,x=a.x=b.x=c}
(a,b-c)={x|x,a,b,c属于Q,x=a或者b<x<c}

输入:

()

(75)

(1,3-100)|(2,10,3-99)&(100,200)^(75)

结果为(75,100)(无先后顺序)

  (1,24,124-)

思路:

数据集合的原始处理

栈,(进,)出。

(进,判断,1进,3-100,3-100出,1出,处理,1,3-100,进,|进,(进,2进,

# coding: utf-8


class Collection(object):
    def __init__(self, raw_input):
        self.raw_data = raw_input
        self.data_stack = []
        self.sign_stack = []

    # loop str
    # para sytnax return
    # loop data_stack
    # find collections
    def get_collection(self):
        if not self.check_format():
            return 'NAN'

        pre_char=''
        for char in self.raw_data:
            if '(' in char:
                self.data_stack.append('(')
            if ')' in char:
                union_str = ''
                while self.data_stack[-1] != '(':
                    top_data = self.data_stack.pop()
                    union_str = union_str + ',' + top_data
                self.data_stack.pop()
                print(union_str)
                self.data_stack.append(union_str)
            if char not in ',' and char i:
                pass
            pre_char = char

    def check_format(self):
        if len(self.raw_data) == 0:
            return False
        if '(' in self.raw_data or ')' in self.raw_data:
            return False
        if self.raw_data[0] != '(':
            return False
        return True


if __name__ == '__main__':
    str = '(1,2,3,4)'
    create_collection = Collection(str)
    create_collection.get_collection()
    print(create_collection.data_stack)

修改:

range_info.py:

# encoding: UTF-8
from set_operations.doublestackprocessor import DoubleStackProcessor

valid_char = '|&^,-()'
MAX_SIZE = 4294967295


class Expression(object):
    def __init__(self, expr, context=None):
        if context == None:
            self.ctx = Context(expr, 0)
        else:
            self.ctx = context
        self.dsp = DoubleStackProcessor()

    def eval(self):
        while self.ctx.expr_not_end():
            c = self.ctx.next_char()
            if c == '(':
                self.dsp.push_operand_stack(Expression(self.ctx.expr, self.ctx).eval())
                if len(self.dsp._operand_stack) == 2 and len(self.dsp._operator_stack) == 1:
                    l = self.dsp._operand_stack.pop()
                    r = self.dsp._operand_stack.pop()
                    operator = self.dsp._operator_stack.pop()
                    self.dsp.push_operand_stack(self.dsp.apply(operator, l, r))
            elif c == ')':
                return self.dsp.transfer_intervals()
            else:
                self.dsp.process(c)
        print(self.dsp._operand_stack, self.dsp._operator_stack,77777)

    def check_format(self):
        check_valid_char = self.ctx.is_valid_char
        check_empty = self.ctx.empty_parentheses
        check_valid_expr = self.ctx.is_valid_expr
        return check_valid_char() or check_empty() or check_valid_expr()

    def mainloop(self):
        print(self.check_format())
        if self.check_format():
            return '(NAN)'
        self.eval()

import re

class Context(object):
    def __init__(self, expr, cur_idx=0):
        self.expr = Context.replace_empty(expr)
        self.cur_idx = cur_idx

    def expr_not_end(self):
        return self.cur_idx != len(self.expr)

    def next_char(self):
        c = self.expr[self.cur_idx]
        self.cur_idx = self.cur_idx + 1
        return c

    @staticmethod
    def replace_empty(expr):
        return expr.replace(' ', '')

    def is_valid_char(self):
        for c in self.expr:
            if c not in valid_char and not c.isdigit():
                return True
        return False

    def empty_parentheses(self):
        return self.expr == '()'

    @staticmethod
    def _is_overflow(c):
        return c > MAX_SIZE

    def is_valid_expr(self):
        replace_difference_expr = self.expr.replace(')-(', ')&(')
        range_info_list = re.split(r'[&|^]', replace_difference_expr)
        for data in range_info_list:
            if Context._check_operand(data):
                return True
        return False

    @staticmethod
    def _check_operand(sub_str):
        if Context._logic_parentheses(sub_str):
            return True
        operand_list = sub_str[1:-1].split(',')
        print (operand_list,99999)
        for operand in operand_list:
            if operand.isdigit() and Context._is_overflow(int(operand)):
                return True
            if operand.isdigit():
                continue
            if Context._check_hyphen(operand):
                return True
        return False

    @staticmethod
    def _logic_parentheses(sub_str):
        check_beg_end = not (sub_str[0] == '(' and sub_str[-1] == ')')
        check_more_parentheses = '(' in sub_str[1:-1] or ')' in sub_str[1:-1]
        check_dot = ',,' in sub_str
        return check_dot or check_beg_end or check_more_parentheses

    @staticmethod
    def _check_hyphen(operand):
        if '-' not in operand:
            return False
        if operand.count('-') > 1 or operand[0] == '-' or operand[1] == '-':
            return True
        l, r = operand.split('-')
        if int(l) > MAX_SIZE or int(r) > MAX_SIZE or int(l) > int(r):
            return True
        return False


doublestackprocessor.py

# encoding: UTF-8
from set_operations.operators import Operators


class DoubleStackProcessor(object):
    operator_map_func = {'|': Operators.union,
                         '&': Operators.intersection}

    def __init__(self):
        self._operand_stack = []
        self._operator_stack = []
        self.cache_stack = []

    def push_operand_stack(self, c):
        self._operand_stack.append(c)

    def push_cache_stack(self, c):
        self.cache_stack.append(c)

    def push_operator_stack(self, c):
        self._operator_stack.append(c)

    def process(self, c):
        print('c', c)
        if c.isdigit():
            self.push_cache_stack(c)
        elif c == ',':
            self.process_cache()
        elif c == '-':
            if len(self.cache_stack) > 0:
                self.push_cache_stack(c)
            else:
                self.push_operator_stack(c)
        else:
            self.push_operator_stack(c)

    def process_cache(self):
        if len(self.cache_stack) == 0:
            return
        operand = ''.join(self.cache_stack)
        self.push_operand_stack(operand)
        self.cache_stack = []

    def transfer_intervals(self):
        self.process_cache()
        useful_stack = []
        while self.operand_not_empty():
            c = self._operand_stack.pop()
            if c.isdigit():
                useful_stack.append([int(c), int(c)])
            else:
                l, r = c.split('-')
                useful_stack.append([int(l), int(r)])
            useful_stack.sort(key=lambda x: x[0])
        return DoubleStackProcessor.merge_intervals(useful_stack)

    def operand_not_empty(self):
        return len(self._operand_stack) != 0

    @staticmethod
    def apply(operator, l_operand, r_operand):
        return DoubleStackProcessor.operator_map_func[operator](l_operand, r_operand)

    @staticmethod
    def merge_intervals(intervals):
        res = []
        l, r = intervals[0]
        len_intervals = len(intervals)
        for i in range(1, len_intervals):
            beg, end = intervals[i]
            if r + 1 < beg:
                res.append([l, r])
                l, r = beg, end
            else:
                r = max(r, end)
        res.append([l, r])
        return res


operator.py

# encoding :utf-8

class Operators(object):
    def __init__(self):
        pass

    @staticmethod
    def union(a, b):
        a.extend(b)
        return Operators.union_intervals(a)

    @staticmethod
    def intersection(a, b):
        return Operators.intersection_intervals(a, b)

    @staticmethod
    def difference(a, b):
        return Operators.difference_intervals(a, b)

    @staticmethod
    def difference_intervals(a, b):
        res = []
        i, j, len_a, len_b = 0, 0, len(a), len(b)
        while i<len_a and j<len_b:
            pass



    @staticmethod
    def union_intervals(intervals):
        intervals.sort(key=lambda x: x[0])
        res = []
        l, r = intervals[0]
        len_intervals = len(intervals)
        for i in range(1, len_intervals):
            beg, end = intervals[i]
            if r + 1 < beg:
                res.append([l, r])
                l, r = beg, end
            else:
                r = max(r, end)
        res.append([l, r])
        return res

    @staticmethod
    def intersection_intervals(a, b):
        res = []
        i, j, len_a, len_b = 0, 0, len(a), len(b)
        while i < len_a and j < len_b:
            l, r = max(a[i][0], b[j][0]), min(a[i][1], b[j][1])
            if l <= r:
                res.append([l, r])
            if a[i][1] < b[j][1]:
                i = i + 1
            else:
                j = j + 1
        return res

Guess you like

Origin blog.csdn.net/cwcww1314/article/details/120121066