Maximum sub-array question:
For question details, see Introduce to algorithm-----Chapter 4.
Because This blog only keeps codes, so here i just give the real code in C/C++, no more summaries :
template <typename T>
struct ret_info
{
int low;
int high;
T sum;
};
template <typename T>
ret_info<T> find_max_crossing_subarray
(T* A, int low, int mid, int high)
{
T left_sum = INT_MIN;
T sum = 0;
int max_left;
for (int i = mid; i >= low; --i)
{
sum += A[i];
if (sum >= left_sum)
max_left = i,
left_sum = sum;
}
T right_sum = INT_MIN;
sum = 0;
int max_right;
for (int i = mid + 1; i <= high; ++i)
{
sum += A[i];
if (sum >= right_sum)
right_sum = sum,
max_right = i;
}
ret_info<T> ret;
ret.low = max_left;
ret.high = max_right;
ret.sum = left_sum + right_sum;
return ret;
}
template <typename T>
ret_info<T> find_maximum_subarray
(T* A, int low, int high)
{
if (low == high)
{
ret_info<T> ret;
ret.low = low;
ret.high = high;
ret.sum = A[low];
return ret;
}
else
{
int mid = (low + high) / 2;
ret_info<T> left_ret, right_ret, cross_ret;
left_ret = find_maximum_subarray (A, low, mid);
right_ret = find_maximum_subarray (A, mid + 1, high);
cross_ret = find_max_crossing_subarray (A, low, mid, high);
if (left_ret.sum >= right_ret.sum && left_ret.sum >= cross_ret.sum)
return left_ret;
else if (right_ret.sum >= left_ret.sum && right_ret.sum >= cross_ret.sum)
return right_ret;
else return cross_ret;
}
}
Strassen algorithm:
template <typename T>
struct split_matrix
{
T* ptr;
int max_len;
};
//assume A, B, C are all N X N matrixs
template <typename T>
void square_matrix_multiply (split_matrix<T> C,
split_matrix<T> A,
split_matrix<T> B,
int n)
{
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
{
C.ptr[i * C.max_len + j] = 0;
for (int k = 0; k < n; ++k)
C.ptr[i * C.max_len + j] += A.ptr[i * C.max_len + k] * B.ptr[k * C.max_len + j];
}
}
//n is the dimension of matrix
template <typename T>
void square_matrix_multiply_recursive (split_matrix<T> C,
split_matrix<T> A,
split_matrix<T> B,
int n)
{
split_matrix<T> ori_C = C, ori_B = B, ori_A = A;
if (n == 1)
C.ptr[0] = A.ptr[0] * B.ptr[0];
else
{
square_matrix_multiply_recursive (C, A, B, n / 2);
A.ptr = ori_A.ptr + n / 2;
B.ptr = ori_B.ptr + n / 2 * B.max_len;
square_matrix_multiply_recursive (C, A, B, n / 2);
C.ptr = ori_C.ptr + n / 2;
B.ptr = ori_B.ptr + n / 2;
square_matrix_multiply_recursive (C, ori_A, B, n / 2);
A.ptr = ori_A.ptr + n / 2;
B.ptr = ori_B.ptr + n / 2 * B.max_len + n / 2;
square_matrix_multiply_recursive (C, A, B, n / 2);
A.ptr = ori_A.ptr + n / 2 * A.max_len;
C.ptr = ori_C.ptr + n / 2 * C.max_len;
square_matrix_multiply_recursive (C, A, ori_B, n /2);
A.ptr = ori_A.ptr + n / 2 * A.max_len + n / 2;
B.ptr = ori_B.ptr + n / 2 * B.max_len;
square_matrix_multiply_recursive (C, A, B, n / 2);
C.ptr = ori_C.ptr + n / 2 * C.max_len + n / 2;
A.ptr = ori_A.ptr + n / 2 * A.max_len;
B.ptr = ori_B.ptr + n / 2;
square_matrix_multiply_recursive (C, A, B, n / 2);
A.ptr = ori_A.ptr + n / 2 * A.max_len + n / 2;
B.ptr = ori_B.ptr + n / 2 * B.max_len + n / 2;
square_matrix_multiply_recursive (C, A, B, n / 2);
}
}