Breadth-first search (BFS)

BFS is a traversing algorithm that starts at the tree root and explores all nodes at the present depth prior to moving on to the nodes at the next depth level. Extra memory is needed to keep track of the child nodes that were encountered but not yet explored.

 

The traversing process is as follows:

Pseudocode

BFS(G, root) is
	let Q be a queue
    label root as explored
    Q.enqueue(root) // insert a tree root in queue until every neighbour vertices are marked
    while Q is not empty do:
    	v := Q.dequeue() // remove a to-be-visited vertex from queue
        if v is the goal then
        	return v
        for all edges from v to w in G.adjacentEdges(v) do:
        	if w is not labelled as explored then
            	label w as explored
                Q.enqueue(w) // store w in Q if it's not visited
        end for
    end while
end

 

Depth-first search (DFS)

DFS is a traversing algorithm that starts at the root node (selecting some arbitrary node as the root node in the case of a graph) and explores as far as possible along each branch before backtracking.

 

The traversing process is as follows:

Pseudocode

DFS(G,v) // v is the vertex where the search starts
	Stack S := {}; // start with an empty stack
    for each vertex u, set visited[u] := false
    	push S, v;
        while S is not empty do:
        	u := pop S;
            if u is not visited then
            	visited[u] := true;
                for each unvisited neighbout w of u
                	push S, w;
                end for
         end while
     end for
end

 

Example

The number of vertices: 4

The number of edges: 5

Start node: 1

#include <iostream>
#include <queue>

#define MAX_VAL 1001

int N, M, V;
int mat[MAX_VAL][MAX_VAL];
bool visited[MAX_VAL];

using namespace std;
void dfs(int v)
{
    printf("%d, ", v);
    visited[v] = true;
    for (int i = 1; i <= N; i++)
    {
        if (visited[i] || mat[v][i] == 0)
            continue;
        dfs(i);
    }
}

void bfs(int v)
{
    queue<int> q;
    q.push(v);
    visited[v] = true;
    while (!q.empty())
    {
        v = q.front();
        printf("%d, ", q.front());
        q.pop();
        for (int i = 1; i <= N; i++)
        {
            if (visited[i] || mat[v][i] == 0)
                continue;
            q.push(i);
            visited[i] = true;
        }
    }
}

int main()
{
    int x, y;
    cin >> N >> M >> V;
    for (int i = 0; i < M; i++)
    {
        cin >> x >> y;
        mat[x][y] = mat[y][x] = 1;
    }
    memset(visited, false, sizeof(visited));
    dfs(V);
    prinft("\n");
    memset(visited, false, sizeof(visited));
    bfs(V);
}

 

Complexity

  BFS DFS
Time O(|V| + |E|) O(|V| + |E|)
Space O(|V|) O(|V|)
  • |V| is the number of vertices
  • |E| is the number of edges

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

 

Example 1:

Input: l1 = [2,4,3], l2 = [5,6,4] Output: [7,0,8] Explanation: 342 + 465 = 807.

Example 2:

Input: l1 = [0], l2 = [0] Output: [0]

Example 3:

Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9] Output: [8,9,9,9,0,0,0,1]

 

Constraints:

  • The number of nodes in each linked list is in the range [1, 100].
  • 0 <= Node.val <= 9
  • It is guaranteed that the list represents a number that does not have leading zeros.
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        int sum = 0;
        ListNode* ans = new ListNode(0);
        ListNode* cur = ans;
        while (l1 != NULL || l2 != NULL)
        {
            if (l1 != NULL)
            {
                sum += l1->val;
                l1 = l1->next;
            }
            if (l2 != NULL)
            {
                sum += l2->val;
                l2 = l2->next;
            }
            
            cur->next = new ListNode(sum % 10);
            cur = cur->next;
            
            sum /= 10;
        }
        if (sum == 1)
        {
            cur->next = new ListNode(1);
        }
        
        return ans->next;
    }
};

0             1             (x + y)^0 = 1
1           1   1           (x + y)¹ = x + y
2         1   2   1         (x + y)² = x² + 2xy + y²
3       1   3   3   1       (x + y)³ = x³ + 3x²y + 3xy² + y³
4     1   4   6   4   1     (x + y)⁴ = x⁴ + 4x³y + 6x²y² + 4xy³ + y⁴
5   1   5   10   10   5   1   (x + y)^5 = x^5 + 5x⁴y + 10x³y² + 10x²y³ + 5xy⁴ + y^5
    0   1   2   3   4   5    

ROW[5][1] = ROW[4][1] + ROW[4][2] = 1 + 4 = 5

ROW[4][3] = ROW[3][2] + ROW[3][3] = 3 + 1 = 4

ROW[2][1] = ROW[1][0] + ROW[1][1] = 1 + 1 + 2

 

 

Pascal's rule (or Pascal's formula) is a combinatorial identity about binomial coefficients.

It states that for positive natural numbers n and k,

where

is a binomial coefficient;

  • one interpretation of which is the coefficient of the x^k term in the expansion of (1 + x)ⁿ. 
  • There is no restriction on the relative sizes of n and k, since if n < k the value of the binomial coefficient is zero and the identity remains valid.

 

Combinatorial proof

Pascal's rule has an intuitive combinatorial meaning, which is clearly expressed in this counting proof.

equals the number of subsets with k elements from a set with n elements.

 

Suppose one particular element is uniquely labelled X in a set with n elements.

  1. To construct a subset of k elements containing X, include X and choose k - 1 elements from the remaining n - 1 elements in the set. There are
    such subsets.
  2. To construct a subset of k elements not containing X, choose k elements from the remaining n - 1 elements in the set. There are
    such subsets.

The total number of subsets with k elements in a set of n elements is

  • the number of subsets containing X (1) + the number of subsets that do not contain X (2)

 

Algebraic proof

 

'Mathematics' 카테고리의 다른 글

Moore-Penrose inverse 무어-펜로즈 의사역행렬  (0) 2023.09.13
Gram-Schmidt orthogonalization  (0) 2023.07.24
Combinations with repetition  (0) 2021.08.26
Permutation with repetition  (0) 2021.08.26
Combinations without repetition  (0) 2021.08.26

lexical analysis, lexing or tokenisation is the process of converting a sequence of characters (such as in a computer programme or web page) into a sequence of tokens (strings with an assigned and thus identified meaning).

 

A programme that performs lexical analysis may be termed a lexer, tokeniser, or scanner, although scanner is also a term for the first stage of a lexer. A lexer is generally combined with a parser, which together analyse the syntax of programming languages, web pages, and so forth.

 

Lexical Analysis can be implemented with the deterministic finite automata.

2021.08.27 - [CS_Theory] - [Regular Languages] Determinism (DFA)

 

[Regular Languages] Determinism (DFA)

 

sorapark.tistory.com

The output is a sequence of tokens, which is sent to the parser for syntax analysis.

 

  Read characters   Token  
Input
Lexical Analyser
Syntax Analyser
  Push back extra characters   Ask for token  

 

Lexeme

  • lexeme is a sequence of characters in the source programme that matches the pattern for a token and is identified by the lexical analyser as an instance of that token.
  • Some authors term this a "token", using "token" interchangeably to represent the string being tokenised, and the token data structure resulting from putting this string through the tokenisation process.

Token

  • A lexical token or simply token is a string with an assigned and thus identified meaning.
  • It is structured as a pair consisting of a token name and an optional token value.

The token name is a category of lexical unit. Common token names are:

  1. identifier: names the programmer chooses
    ex) x, colour and UP
  2. keyword: names already in the programming language
    ex) ifwhile and return
  3. separator (also known as punctuators): punctuation characters and paired-delimiters
    ex) }, ( and ;
  4. operator: symbols that operate on arguments and produce results
    ex) +, < and =
  5. literal: numeric, logical, textual, reference literals
    ex) true6.02e23 and "music"
  6. comment: line, block (depends on the compiler if compiler implements comments as tokens otherwise it will be stripped)
    ex) /* */ and //

For example, 

x = a + b * 2;

All the valid tokens are:

  • x
  • =
  • a
  • +
  • b
  • *
  • 2
  • ;

 

The lexical analysis of the expression yields the following sequence of tokens:

[(identifier, x), (operator, =), (identifier, a), (operator, +), (identifier, b), (operator, *), (literal, 2), (separator, ;)]

 

+ Recent posts