Пример #1
0
    def __init__(self, regex):
        """Initializes the NFA from the specified regular expression.

        :param regex: the regular expression

        """
        self.regex = regex
        m = len(regex)
        self.m = m
        ops = Stack()
        graph = Digraph(m + 1)
        for i in range(0, m):
            lp = i
            if regex[i] == "(" or regex[i] == "|":
                ops.push(i)
            elif regex[i] == ")":
                or_ = ops.pop()

                # 2-way or operator
                if regex[or_] == "|":
                    lp = ops.pop()
                    graph.add_edge(lp, or_ + 1)
                    graph.add_edge(or_, i)
                elif regex[or_] == "(":
                    lp = or_
                else:
                    assert False
            if i < m - 1 and regex[i + 1] == "*":
                graph.add_edge(lp, i + 1)
                graph.add_edge(i + 1, lp)
            if regex[i] == "(" or regex[i] == "*" or regex[i] == ")":
                graph.add_edge(i, i + 1)
        if ops.size() != 0:
            raise ValueError("Invalid regular expression")
        self.graph = graph
Пример #2
0
def check_syntax(s: str):
    stack = Stack()
    map_ = {
        "(": [0, 1],
        "[": [0, 2],
        "{": [0, 3],
        ")": [1, 1],
        "]": [1, 2],
        "}": [1, 3]
    }

    for cha in s.strip():
        if map_[cha][0] == 0:
            stack.push(map_[cha][1])
        elif map_[cha][0] == 1:
            try:
                if stack.peek() == map_[cha][1]:
                    stack.pop()
                else:
                    return "0"
            except:
                return "0"

    if stack.is_empty() == True:
        return "1"
    else:
        return "0"
Пример #3
0
def evaluate():
    ops = Stack()
    vals = Stack()

    while not stdio.isEmpty():
        # Read token, push if operator
        s = stdio.readString()
        if   s == "(": pass
        elif s == "+":      ops.push(s)
        elif s == "-":      ops.push(s)
        elif s == "*":      ops.push(s)
        elif s == "/":      ops.push(s)
        elif s == "sqrt":   ops.push(s)
        elif s == ")":
            # Pop, evaluate and push result if token is ")"
            op = ops.pop()
            v = vals.pop()
            if   op == "+":     v = vals.pop() + v
            elif op == "-":     v = vals.pop() - v
            elif op == "*":     v = vals.pop() * v
            elif op == "/":     v = vals.pop() / v
            elif op == "sqrt":  v = math.sqrt(v)
            vals.push(v)
        else:   
            vals.push(float(s))
    stdio.writeln(vals.pop())
class DepthFirstOrder:
    def __init__(self, G):
        self._G = G
        self._pre = Queue()
        self._post = Queue()
        self._reverse_post = Stack()

        self._marked = [False] * G.V()
        for v in range(G.V()):
            if not self._marked[v]:
                self.dfs(v)

    def dfs(self, v):
        self._pre.enqueue(v)
        self._marked[v] = True

        for w in self._G.adj(v):
            if not self._marked[w]:
                self.dfs(w)

        self._post.enqueue(v)
        self._reverse_post.push(v)

    def pre(self):
        return self._pre

    def post(self):
        return self._post

    def reverse_post(self):
        return self._reverse_post
Пример #5
0
def convert_binary(n):
    stack = Stack()
    while n > 0:
        stack.push(n % 2)
        n //= 2
    string = ''
    for i in stack:
        string += str(i)
    return string
Пример #6
0
 def path_to(self, v):
     if not self.has_path_to(v):
         return None
     path = Stack()
     e = self._edge_to[v]
     while e is not None:
         path.push(e)
         e = self._edge_to[e.from_vertex()]
     return path
Пример #7
0
 def path_to(self, v):
     if not self.has_path_to(v):
         return None
     path = Stack()
     x = v
     while x != self._s:
         path.push(x)
         x = self._edgeTo[x]
     path.push(self._s)
     return path
Пример #8
0
    def reverse_post(self):
        """Returns the vertices in reverse postorder.

        :return: the vertices in reverse postorder, as an iterable of vertices

        """
        reverse = Stack()
        for v in self._postorder:
            reverse.push(v)
        return reverse
 def path_to(self, v: int):
     if not self.has_path_to(v):
         return None
     path = Stack()
     curr = v
     while curr != self._s:
         path.push(curr)
         curr = self._edgeto[curr]
     path.push(self._s)
     return path
Пример #10
0
 def path_to(self, v):
     self._validate_vertex(v)
     if self.has_negative_cycle():
         raise UnsupportedOperationException("Negative cost cycle exists")
     if not self.has_path_to(v): return None
     path = Stack()
     e = self._edgeTo[v]
     while e is not None:
         path.push(e)
         e = self._edgeTo[e.from_vertex()]
     return path
Пример #11
0
    def path_to(self, v):
        """Returns a longest path from the source vertex s to vertex v.

        :param: the destination vertex
        :returns: a longest path from the source vertex s to vertex v as an iterable of edges, and None if no such path

        """
        self._validate_vertex(v)
        if not self.has_path_to(v):
            return None
        path = Stack()
        edge = self._edge_to[v]
        while edge is not None:
            path.push(edge)
            edge = self._edge_to[edge.from_vertex()]
        return path
Пример #12
0
    def path_to(self, v: int) -> Iterable:
        """
        return an iterable path object which is shortest from s to v

        :param v:
        :return:
        """
        if not self.has_path_to(v):
            return None
        path = Stack()
        x = v
        while self._dist_to[x] != 0:
            path.push(x)
            x = self._edgeTo[x]
        path.push(x)
        return path
Пример #13
0
    def from_graph(G):
        """Initializes a new graph that is a deep copy of G.

        :param G: the graph to copy
        :returns: copy of G

        """
        g = Graph(G.V())
        g._E = G.E()
        for v in range(G.V()):
            # reverse so that adjacency list is in same order as original
            reverse = Stack()
            for w in G._adj[v]:
                reverse.push(w)
            for w in reverse:
                g._adj[v].add(w)
Пример #14
0
 def from_graph(G):
     """
     Initializes a new edge-weighted graph that is a deep copy of G.
     :param G: the edge-weighted graph to copy
     :return: the copy of the graph edge-weighted graph G
     :rtype: EdgeWeightedGraph
     """
     g = EdgeWeightedGraph(G.V())
     g._E = G.E()
     for v in range(G.V()):
         reverse = Stack()
         for e in G.adj(v):
             reverse.push(e)
         for e in reverse:
             g._adj[v].add(e)
     return g
Пример #15
0
 def path_to(self, v):
     """
     Returns a shortest path from the source vertex s to vertex v.
     :param v: the destination vertex
     :returns: a shortest path from the source vertex s to vertex v
             as an iterable of edges, and None if no such path
     :raises ValueError: unless 0 <= v < V
     """
     self._validate_vertex(v)
     if not self.has_path_to(v): return None
     path = Stack()
     e = self._edge_to[v]
     while e is not None:
         path.push(e)
         e = self._edge_to[e.from_vertex()]
     return path
Пример #16
0
 def path_to(self, v):
     """
     Returns a shortest path from the source vertex s to vertex v.
     :param v: the destination vertex
     :return: a shortest path from the source vertex s to vertex v
     :rtype: collections.iterable[DirectedEdge]
     :raises IllegalArgumentException: unless 0 <= v < V
     """
     self._validate_vertex(v)
     if not self.has_path_to(v):
         return None
     path = Stack()
     e = self._edge_to[v]
     while e is not None:
         path.push(e)
         e = self._edge_to[e.from_vertex()]
     return path
Пример #17
0
    def path_to(self, v):
        """Returns a shortest path between the source vertex s (or sources) and
        v, or null if no such path.

        :param v: the vertex
        :returns: the sequence of vertices on a shortest path, as an Iterable
        :raises ValueError: unless 0 <= v < V

        """
        if not self.has_path_to(v):
            return None
        path = Stack()
        x = v
        while self._dist_to[x] != 0:
            path.push(x)
            x = self._edgeTo[x]
        path.push(x)
        return path
Пример #18
0
 def path_to(self, v):
     """
     Returns a path between the source vertex s and vertex v, or
     None if no such path.
     :param v: the vertex
     :returns: the sequence of vertices on a path between the source vertex
                s and vertex v, as an Iterable
     :raises ValueError: unless 0 <= v < V
     """
     self._validateVertex(v)
     if not self._marked[v]: return None
     path = Stack()
     w = v
     while w != self._s:
         path.push(w)
         # find w's parent link vertex,recursively until reach source.
         w = self._edgeTo[w]
     path.push(self._s)
     return path
Пример #19
0
    def path_to(self, v):
        """
        Returns a path between the source vertex s and vertex v, or
        None if no such path.
        :param v: the vertex
        :returns: the sequence of vertices on a path between the source vertex
                   s and vertex v, as an Iterable
        :raises ValueError: unless 0 <= v < V
        """
        self._validateVertex(v)
        if not self.has_path_to(v): return None
        path = Stack()
        w = v
        while w != self._s:
            path.push(w)
            w = self._edgeTo[w]
        path.push(self._s)

        return path
class DirectedCycle:
    def __init__(self, digraph):
        self._cycle = None
        self._on_stack = [False] * digraph.V()
        self._edge_to = [0] * digraph.V()
        self._marked = [False] * digraph.V()
        for v in range(digraph.V()):
            if not self._marked[v]:
                self._dfs(digraph, v)

    # check that algorithm computes either the topological order or finds a directed cycle
    def _dfs(self, digraph, v):
        self._on_stack[v] = True
        self._marked[v] = True
        for w in digraph.adj(v):
            # short circuit if directed cycle found
            if self.has_cycle():
                return
            # found new vertex, so recur
            elif not self._marked[w]:
                self._edge_to[w] = v
                self._dfs(digraph, w)
            # found a cycle if adj vertex on current recursive directed path
            elif self._on_stack[w]:
                self._cycle = Stack()  # data structure to trace back cycle
                # trace back starting from vertex before creating loop (v)
                x = v
                while x != w:  # iterate back until at vertex that creates cycle
                    self._cycle.push(x)
                    x = self._edge_to[x]
                # push cycle node on stack and initial node to complete cycle (at least two equal vertices)
                self._cycle.push(w)
                self._cycle.push(v)

        # remove current vertex from on stack if all neighbours if we move up one recursive level
        self._on_stack[v] = False

    def has_cycle(self):
        return self._cycle is not None

    def cycle(self):
        return self._cycle
Пример #21
0
 def path_to(self, v):
     """
     Returns a shortest path between the source vertex s and vertex v.
     :param v: the destination vertex
     :return: a shortest path between the source vertex s and vertex v.
     None if no such path
     :rtype: collections.iterable[Edge]
     :raises IllegalArgumentException: unless 0 <= v < V
     """
     self._validate_vertex(v)
     if not self.has_path_to(v):
         return None
     path = Stack()
     x = v
     e = self._edge_to[v]
     while e is not None:
         edge = self._edge_to[x]
         path.push(edge)
         x = e.other(x)
         e = self._edge_to[x]
     return path
Пример #22
0
class Bipartite:
    """
    The Bipartite class represents a data type for 
    determining whether an undirected graph is bipartite or whether
    it has an odd-length cycle.
    The isBipartite operation determines whether the graph is
    bipartite. If so, the color operation determines a
    bipartition if not, the oddCycle operation determines a
    cycle with an odd number of edges.
    
    This implementation uses depth-first search.
    The constructor takes time proportional to V + E
    (in the worst case),
    where V is the number of vertices and E is the number of edges.
    Afterwards, the isBipartite and color operations
    take constant time the oddCycle operation takes time proportional
    to the length of the cycle.
    See BipartiteX for a nonrecursive version that uses breadth-first
    search.
    """
    class UnsupportedOperationException(Exception):
        pass

    def __init__(self, G):
        """
        Determines whether an undirected graph is bipartite and finds either a
        bipartition or an odd-length cycle.

        :param G: the graph
        """
        self._is_bipartite = True  # is the graph bipartite?
        self._color = [
            False
        ] * G.V()  # color[v] gives vertices on one side of bipartition
        self._marked = [
            False
        ] * G.V()  # marked[v] = True if v has been visited in DFS
        self._edge_to = [0] * G.V()  # edgeTo[v] = last edge on path to v
        self._cycle = None  # odd-length cycle

        for v in range(G.V()):
            if not self._marked[v]:
                self._dfs(G, v)

        assert self._check(G)

    def _dfs(self, G, v):
        self._marked[v] = True

        for w in G.adj(v):
            # short circuit if odd-length cycle found
            if self._cycle is not None: return

            # found uncolored vertex, so recur
            if not self._marked[w]:
                self._edge_to[w] = v
                self._color[w] = not self._color[v]
                self._dfs(G, w)

            # if v-w create an odd-length cycle, find it
            elif self._color[w] == self._color[v]:
                self._is_bipartite = False
                self._cycle = Stack()
                self._cycle.push(
                    w
                )  # don't need this unless you want to include start vertex twice
                x = v
                while x != w:
                    self._cycle.push(x)
                    x = self._edge_to[x]

                self._cycle.push(w)

    def is_bipartite(self):
        """
        Returns True if the graph is bipartite.
        
        :returns: True if the graph is bipartite False otherwise
        """
        return self._is_bipartite

    def color(self, v):
        """
        Returns the side of the bipartite that vertex v is on.

        :param v: the vertex
        :returns: the side of the bipartition that vertex v is on two vertices
                are in the same side of the bipartition if and only if they have the
                same color
        :raises IllegalArgumentException: unless 0 <= v < V 
        :raises UnsupportedOperationException: if this method is called when the graph
                is not bipartite
        """
        self._validateVertex(v)
        if not self._is_bipartite:
            raise Bipartite.UnsupportedOperationException(
                "graph is not bipartite")
        return self._color[v]

    def odd_cycle(self):
        """
        Returns an odd-length cycle if the graph is not bipartite, and
        None otherwise.
        
        :returns: an odd-length cycle if the graph is not bipartite
                (and hence has an odd-length cycle), and None otherwise
        """
        return self._cycle

    def _check(self, G):
        # graph is bipartite
        if self._is_bipartite:
            for v in range(G.V()):
                for w in G.adj(v):
                    if self._color[v] == self._color[w]:
                        error = "edge {}-{} with {} and {} in same side of bipartition\n".format(
                            v, w, v, w)
                        print(error, file=sys.stderr)
                        return False
        # graph has an odd-length cycle
        else:
            # verify cycle
            first = -1
            last = -1
            for v in self.odd_cycle():
                if first == -1:
                    first = v
                last = v

            if first != last:
                error = "cycle begins with {} and ends with {}\n".format(
                    first, last)
                print(error, file=sys.stderr)
                return False
        return True

    def _validateVertex(self, v):
        # raise an ValueError unless 0 <= v < V
        V = len(self._marked)
        if v < 0 or v >= V:
            raise ValueError("vertex {} is not between 0 and {}".format(
                v, V - 1))
class EdgeWeightedDirectedCycle:
    """The EdgeWeightedDirectedCycle class represents a data type for
    determining whether edge-weighted digraph has a directed cycle. The
    hasCycle operation determines whether the edge-weighted digraph has a
    directed cycle and, if so, the cycle operation returns one.

    This implementation uses depth-first search. The constructor takes time proportional to
    V + E (in the worst case), where V is the number of vertices and E is the number of edges.
    Afterwards, the hasCycle operation takes constant time; the cycle operation takes time
    proportional to the length of the cycle.

    See Topological to compute a topological order if the edge-weighted digraph is acyclic.

    For additional documentation, see Section 4.4 of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

    """
    def __init__(self, edge_weighted_digraph):
        """Determines whether the edge weighted digraph has a directed cycle
        and, if so, finds such a cycle.

        :digraph: the digraph

        """
        self._cycle = None
        self._on_stack = [False] * edge_weighted_digraph.V()
        self._edge_to = [None] * edge_weighted_digraph.V()
        self._marked = [False] * edge_weighted_digraph.V()
        for v in range(edge_weighted_digraph.V()):
            if not self._marked[v]:
                self._dfs(edge_weighted_digraph, v)

    # check that algorithm computes either the topological order or finds a directed cycle
    def _dfs(self, graph, v):
        self._on_stack[v] = True
        self._marked[v] = True
        for edge in graph.adj(v):
            w = edge.to_vertex()

            # short circuit if directed cycle found
            if self.has_cycle():
                return
            # found new vertex, so recur
            elif not self._marked[w]:
                self._edge_to[w] = edge
                self._dfs(graph, w)
            # trace back directed cycle
            elif self._on_stack[w]:
                self._cycle = Stack()
                f = edge
                while f.from_vertex() != w:
                    self._cycle.push(f)
                    f = self._edge_to[f.from_vertex()]
                self._cycle.push(f)

        self._on_stack[v] = False

    def has_cycle(self):
        """Does the edge weighted digraph have a directed cycle?

        :returns: true if there is a cycle, false otherwise

        """
        return self._cycle is not None

    def cycle(self):
        """Returns a directed cycle if the edge weighted digraph has a directed
        cycle, and null otherwise.

        :returns: a directed cycle (as an iterable) if the digraph has a directed cycle, and null otherwise

        """
        return self._cycle
def evaluate(expression):
    ops = Stack()
    vals = Stack()

    for char in expression:
        if char == '(':
            None
        elif char == '+':
            ops.push('+')
        elif char == '-':
            ops.push('-')
        elif char == '*':
            ops.push('*')
        elif char == '/':
            ops.push('/')
        elif char == ')':
            op = ops.pop()
            v = vals.pop()

            if op == '+':
                v = vals.pop() + v
            elif op == '-':
                v = vals.pop() - v
            elif op == '*':
                v = vals.pop() * v
            elif op == '/':
                v = vals.pop() / v
            vals.push(v)
        else:
            vals.push(int(char))
        #print(f'Operation Stack: {ops}')
        #print(f'Value Stack: {vals}')

    return vals.pop()
Пример #25
0
class Cycle:
    """The Cycle class represents a data type for determining whether an
    undirected graph has a cycle. The hasCycle operation determines whether the
    graph has a cycle and, if so, the cycle operation returns one.

    This implementation uses depth-first search. The constructor takes
    time proportional to V + E (in the worst case), where V is the
    number of vertices and E is the number of edges. Afterwards, the
    hasCycle operation takes constant time the cycle operation takes
    time proportional to the length of the cycle.

    """
    def __init__(self, G):
        """Determines whether the undirected graph G has a cycle and, if so,
        finds such a cycle.

        :param G: the undirected graph

        """
        if self._has_self_loop(G):
            return
        if self._has_parallel_edges(G):
            return
        self._marked = [False] * G.V()
        self._edgeTo = [0] * G.V()
        self._cycle = None
        for v in range(G.V()):
            if not self._marked[v]:
                self._dfs(G, -1, v)

    def _has_self_loop(self, G):
        # does this graph have a self loop?
        # side effect: initialize cycle to be self loop
        for v in range(G.V()):
            for w in G.adj(v):
                if v == w:
                    self._cycle = Stack()
                    self._cycle.push(v)
                    self._cycle.push(w)
                    return True
        return False

    def _has_parallel_edges(self, G):
        # does this graph have two parallel edges?
        # side effect: initialize cycle to be two parallel edges
        self._marked = [False] * G.V()
        for v in range(G.V()):
            # check for parallel edges incident to v
            for w in G.adj(v):
                if self._marked[w]:
                    self._cycle = Stack()
                    self._cycle.push(v)
                    self._cycle.push(w)
                    self._cycle.push(v)
                    return True
                self._marked[w] = True

            for w in G.adj(v):
                self._marked[w] = False
        return False

    def has_cycle(self):
        """Returns true if the graph G has a cycle.

        :returns: true if the graph has a cycle false otherwise

        """
        return self._cycle is not None

    def cycle(self):
        """Returns a cycle in the graph G.

        :returns: a cycle if the graph G has a cycle,
            and null otherwise

        """
        return self._cycle

    def _dfs(self, G, u, v):
        self._marked[v] = True
        for w in G.adj(v):
            # short circuit if cycle already found
            if self._cycle is not None:
                return
            if not self._marked[w]:
                self._edgeTo[w] = v
                self._dfs(G, v, w)
            elif w != u:
                self._cycle = Stack()
                x = v
                while x != w:
                    self._cycle.push(x)
                    x = self._edgeTo[x]
                self._cycle.push(w)
                self._cycle.push(v)
class EdgeWeightedDirectedCycle:
    """Determines whether the edge-weighted digraph G has a directed cycle and,
    if so, finds such a cycle.

    :param G the edge-weighted digraph

    """
    def __init__(self, G):
        self._marked = [False] * G.V()  # marked[v] = has vertex v been marked?
        self._edgeTo = [
            None
        ] * G.V()  # edgeTo[v] = previous DirectedEdge on path to v
        self._onStack = [False] * G.V()  # onStack[v] = is vertex on the stack?
        self._cycle = None  # directed cycle (or None if no such cycle)

        for v in range(G.V()):
            if not self._marked[v]:
                self._dfs(G, v)

        # check that digraph has a cycle
        assert self._check()

    # check that algorithm computes either the topological order or finds a directed cycle
    def _dfs(self, G, v):
        self._onStack[v] = True
        self._marked[v] = True
        for e in G.adj(v):
            w = e.to_vertex()

            # short circuit if directed cycle found
            if self._cycle is not None:
                return

            # found new vertex, so recur
            elif not self._marked[w]:
                self._edgeTo[w] = e
                self._dfs(G, w)

            # trace back directed cycle
            elif self._onStack[w]:
                self._cycle = Stack()
                f = e
                while f.from_vertex() != w:
                    self._cycle.push(f)
                    f = self._edgeTo[f.from_vertex()]

                self._cycle.push(f)
                return
        self._onStack[v] = False

    # Does the edge-weighted digraph have a directed cycle?
    # @return True if the edge-weighted digraph has a directed cycle,
    # False otherwise
    def has_cycle(self):
        return self._cycle is not None

    # Returns a directed cycle if the edge-weighted digraph has a directed cycle,
    # and None otherwise.
    # @return a directed cycle (as an iterable) if the edge-weighted digraph
    #    has a directed cycle, and None otherwise
    def cycle(self):
        return self._cycle

    # certify that digraph is either acyclic or has a directed cycle
    def _check(self):

        # edge-weighted digraph is cyclic
        if self.has_cycle():
            # verify cycle
            first = None
            last = None
            for e in self.cycle():
                if first is None:
                    first = e
                if last is not None:
                    if last.to_vertex() != e.from_vertex():
                        print("cycle edges {} and {} not incident".format(
                            last, e))
                        return False
                last = e

            if last.to_vertex() != first.from_vertex():
                print("cycle edges {} and {} not incident".format(last, first))
                return False

        return True