Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added blogs #1901

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions blog/bit-manupulation-techniques-in-algorithms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
slug: bit-manipulation-techniques-in-algorithms
title: "Bit Manipulation Techniques in Algorithms"
authors: [Harshitha-Grandhi]
tags: [Harshitha-Grandhi, algo, dsa, algorithms, bit-manipulation]
---

Bit manipulation is a powerful technique in computer science, especially useful in optimizing algorithms and managing memory. By operating directly on binary representations, bit manipulation enables us to perform operations efficiently. This blog post will explore various bit manipulation techniques and their applications in algorithms.

<!-- truncate -->

In this blog, we'll cover:

- **Understanding Bit Manipulation**: Basics of binary and bitwise operations.
- **Bitwise Operators**: Key operators like AND, OR, XOR, NOT, and shifts.
- **Common Bit Manipulation Techniques**: Examples and explanations.
- **Applications in Algorithms**: Where and how these techniques are applied.
- **Implementation**: Code examples in Python and Java.
- **Real-World Use Cases**: Practical applications of bit manipulation.

---

## Understanding Bit Manipulation

Bit manipulation involves working directly with individual bits of binary numbers. Each integer is stored as a sequence of bits (0s and 1s), and we can perform operations on them to accomplish tasks more efficiently.

### Basic Bitwise Operators

1. **AND (&)**: Sets each bit to 1 if both bits are 1.
2. **OR (|)**: Sets each bit to 1 if one of the bits is 1.
3. **XOR (^)**: Sets each bit to 1 if only one of the bits is 1.
4. **NOT (~)**: Inverts all bits.
5. **Shift Left (<<)**: Shifts bits to the left, filling with 0s.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace << with `<<` or &lt;&lt;

6. **Shift Right (>>)**: Shifts bits to the right, filling with the sign bit.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace >> with `>>` or &gt;&gt;


## Common Bit Manipulation Techniques

### 1. Swapping Values

Using XOR, you can swap two numbers without a temporary variable:

```python
def swap(a, b):
a = a ^ b
b = a ^ b
a = a ^ b
return a, b
```
### 2. Checking if a Number is Odd or Even
Use the AND operator with 1:

def is_odd(n):
return (n & 1) == 1

Comment on lines +51 to +54
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write within ```

### 3. Setting a Bit
To set the ith bit of a number n:

def set_bit(n, i):
return n | (1 << i)
Comment on lines +57 to +59
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write within ```

### 4. Clearing a Bit
To clear the ith bit:

def clear_bit(n, i):
return n & ~(1 << i)

Comment on lines +62 to +65
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write within ```

## Applications in Algorithms
|Feature |Description |Bit Manipulation Example |
|----------------------|----------------------------------------------|-----------------------------|
|Checking Power of Two |Efficiently determine if n is a power of two |n & (n - 1) == 0 |
|Counting Set Bits |Count the number of 1s in binary |Brian Kernighan's algorithm |
|Subset Generation |Generate subsets in combinatorial problems |Bitwise operations on numbers|

## Code Implementation

## Python Implementation:

# Example: Count set bits in an integer
def count_set_bits(n):
count = 0
while n:
n &= (n - 1) # Clear the least significant bit set
count += 1
return count

Comment on lines +78 to +84
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write within ```

# Example usage
print(count_set_bits(13)) # Output: 3 (binary: 1101)

Comment on lines +86 to +87
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write within ```

## Java Implementation:
public class BitManipulation {
// Count set bits in an integer
public static int countSetBits(int n) {
int count = 0;
while (n > 0) {
n &= (n - 1); // Clear the least significant bit set
count++;
}
return count;
}

public static void main(String[] args) {
System.out.println(countSetBits(13)); // Output: 3 (binary: 1101)
}
}
Comment on lines +89 to +103
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write within ```


## Real-World Use Cases
Bit manipulation is used in various domains, such as:
-**Cryptography**: Encryption algorithms use bit manipulation for security.
-**Graphics Processing**: Optimizing image rendering via bit-level operations.
-**Data Compression**: Reducing data size through bitwise operations.

## Conclusion
Bit manipulation offers efficient ways to perform tasks that would otherwise require more memory or processing time. Understanding these techniques can be highly beneficial in solving algorithmic problems and optimizing code in data structures and algorithms.
176 changes: 176 additions & 0 deletions blog/introduction-to-hashing-and-hash-functions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
---
slug: introduction-to-hashing-and-hash-functions
title: "Introduction to Hashing and Hash Functions"
authors: [Harshitha-Grandhi]
tags: [Harshitha-Grandhi, algo, dsa, algorithms, hashing]
---

Hashing is a fundamental concept in computer science, used to efficiently store and retrieve data. By converting data into a fixed-size numerical value, hash functions enable rapid data access. This blog post will introduce hashing, explore how hash functions work, and discuss their applications in computer science.

<!-- truncate -->

In this blog, we'll cover:

- **What is Hashing?**: A basic understanding of hashing and its purpose.
- **Hash Functions**: How they work and their key properties.
- **Hashing Techniques**: Different types of hashing methods.
- **Applications of Hashing**: Practical use cases in algorithms and systems.
- **Implementation**: Code examples in Python and Java.
- **Real-World Examples**: How hashing is applied in real-life scenarios.

---

## What is Hashing?

Hashing is a technique that maps data of arbitrary size to a fixed size, typically using a hash function. The goal is to assign a unique "hash code" to each data item, enabling quick access to that item within a collection.

### Hashing Example:

Consider a phone book. Instead of searching through all names to find a specific number, we could use a hash function to directly map names to their respective entries, making retrieval faster.

## Hash Functions

A hash function takes input data and returns a fixed-size string or integer, commonly known as a hash code. A good hash function has the following properties:

1. **Deterministic**: The same input always produces the same output.
2. **Efficient**: It computes hash codes quickly.
3. **Uniform Distribution**: It distributes hash values evenly, minimizing collisions.
4. **Low Collision Probability**: Different inputs should rarely produce the same hash code.

### Common Hash Functions

- **Division Method**: Uses modulo operation, `h(x) = x % m`.
- **Multiplication Method**: Uses a constant to multiply and extract part of the result.
- **Universal Hashing**: Combines multiple functions to reduce collision risk.

## Hashing Techniques

### 1. Separate Chaining

Separate chaining handles collisions by storing multiple items in each bucket as a linked list:

```python
class HashTable:
def __init__(self, size):
self.size = size
self.table = [[] for _ in range(size)]

def insert(self, key, value):
hash_key = hash(key) % self.size
self.table[hash_key].append((key, value))

def get(self, key):
hash_key = hash(key) % self.size
for k, v in self.table[hash_key]:
if k == key:
return v
return None

```
### 2. Open Addressing
Open addressing resolves collisions by finding another empty slot in the table.

Linear Probing
Increment by one until an empty slot is found.

python
Copy code
def linear_probe_insert(table, key, value):
index = hash(key) % len(table)
while table[index] is not None:
index = (index + 1) % len(table)
table[index] = (key, value)
Applications of Hashing
Application Description Example Use Case
Caching Store computed results for reuse Web page caching
Data Deduplication Identify and remove duplicate data File storage optimization
Cryptography Protect data through hashing Password storage
Code Implementation
Python Implementation:
python
Copy code
# Simple Hash Table Example using Separate Chaining

```python
class HashTable:
def __init__(self, size):
self.size = size
self.table = [[] for _ in range(size)]

def insert(self, key, value):
hash_key = hash(key) % self.size
self.table[hash_key].append((key, value))

def get(self, key):
hash_key = hash(key) % self.size
for k, v in self.table[hash_key]:
if k == key:
return v
return None

```
# Example usage
hash_table = HashTable(10)
hash_table.insert("name", "Alice")
print(hash_table.get("name")) # Output: Alice

## Java Implementation:

```java
import java.util.LinkedList;

public class HashTable {
private LinkedList<Entry>[] table;

public HashTable(int size) {
table = new LinkedList[size];
for (int i = 0; i < size; i++) {
table[i] = new LinkedList<>();
}
}

private int getHashKey(String key) {
return key.hashCode() % table.length;
}

public void insert(String key, String value) {
int hashKey = getHashKey(key);
table[hashKey].add(new Entry(key, value));
}

public String get(String key) {
int hashKey = getHashKey(key);
for (Entry entry : table[hashKey]) {
if (entry.key.equals(key)) {
return entry.value;
}
}
return null;
}

private static class Entry {
String key;
String value;

Entry(String key, String value) {
this.key = key;
this.value = value;
}
}

public static void main(String[] args) {
HashTable ht = new HashTable(10);
ht.insert("name", "Alice");
System.out.println(ht.get("name")); // Output: Alice
}
}

```
## Real-World Examples
Hashing is widely used in various fields, including:
-**Databases**: Quick retrieval of rows via primary keys.
-**Networking**: Routing packets using hash-based IP lookup.
-**Blockchain**: Cryptographic hashing for securing transactions.

## Conclusion
Hashing and hash functions are vital in computer science, offering efficient ways to store and retrieve data. By understanding and implementing these techniques, you can solve various algorithmic challenges more effectively, especially in areas where quick access to data is crucial.
Loading