#include<iostream>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#include<string>
using namespace std;
//求最大公约数
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b,a%b);
}
//---------------------------
//KMP
//求前缀函数
int *Compute_Prefix_Function(string P, int m)
{
int *t = new int[m + 1];
int k = 0;
t[1] = 0;
for (int s = 2; s <= m; s++)
{
while (k > 0 && P.at(k+1)!= P.at(s))
k = t[k];
if (P.at(k+1) == P.at(s))
k = k + 1;
t[s] = k;
}
return t;
}
//KMP匹配
void Kmp_Matcher(string T, string P)
{
int m = P.length();
int n = T.length();
P = "0" + P;
T = "0" + T;
int *t = Compute_Prefix_Function(P,m);
int k = 0;
for (int i = 1; i <= n; i++)
{
while (k > 0 && P.at(k+1) != T.at(i))
k = t[k];
if (P.at(k + 1) == T.at(i))
k = k + 1;
if (k == m)
{
cout << "matcher at " << i - m << endl;
k = t[k];
}
}
delete[]t;
}
//全排列
void Perm(string list, int i)
{
if (i == list.length())
{
for (unsigned c = 0; c < list.length(); c++)
{
cout << list.at(c) << " ";
}
cout << "\n";
}
else
{
for (unsigned j = i; j < list.length(); j++)
{
swap(list[i], list[j]);
Perm(list,i+1);
swap(list[i],list[j]);
}
}
}
void Perm_Print(string list)
{
Perm(list, 0);
}
//钢条切割
//-------------------------------------------------
//朴素算法
int Cut_Rod(int *P, int n)
{
if (n == 0)
return 0;
int q = -1;
for (int i = 1; i <= n; i++)
{
q = max(q, P[i] + Cut_Rod(P, n - i));
}
return q;
}
//带有备忘的Cut_Rod
int Memoized_Cut_Rod(int *P, int n,int *r)
{
if (r[n] >= 0)
return r[n];
int q = -1;
if (n == 0)
q = 0;
else
{
for (int i = 1; i <= n; i++)
{
q = max(q, P[i] + Memoized_Cut_Rod(P, n - i, r));
}
}
r[n] = q;
return r[n];
}
int Print_Memoized_Cut_Rod(int*P, int n)
{
int *r = new int[n + 1];
for (int i = 0; i <= n; i++)
{
r[i] = -1;
}
int res=Memoized_Cut_Rod(P,n,r);
delete[]r;
return res;
}
//自底向上Cut_Rod
int BottomUp_Cut_Rod(int *P, int n)
{
int *r = new int[n + 1];
r[0] = 0;
for (int i = 1; i <= n; i++)
{
int q = -1;
for (int j = 1; j <= i; j++)
{
q = max(q, P[j] + r[i-j]);
}
r[i] = q;
}
return r[n];
}
//重构最优解
int Print_BottomUp_Cut_Rod(int *P, int n,int *C)
{
int *r = new int[n + 1];
r[0] = 0;
for (int i = 1; i <= n; i++)
{
int q = -1;
for (int j = 1; j <= i; j++)
{
if (q < P[j] + r[i - j])
{
q = P[j] + r[i - j];
C[i] = j;//记录当钢条为i时的最佳切割方案
}
}
r[i] = q;
}
return r[n];
}
int Print_BP_Cut_Rod(int *P, int n)
{
int *C = new int[n + 1];
int res=Print_BottomUp_Cut_Rod(P,n,C);
while (n > 0)
{
cout << C[n] << " ";
n = n - C[n];
}
cout << "\n";
delete[]C;
return res;
}
//-------------------------------------------------
//简单选择排序
void SimpleSelectSort(int *a, int len)
{
int min;
for (int i = 0; i < len; i++)
{
min =i;
for (int j = i + 1; j < len; j++)
{
if (a[j]<a[min])
min = j;
}
if (i != min)
{
swap(a[i], a[min]);
}
}
for (int i = 0; i < len; i++)
{
cout << a[i] << " ";
}
cout << "\n";
}
//-------------------------------------------------
//冒泡排序
void Bubble_Sort(int *a, int len)
{
for (int i = 0; i < len; i++)
{
for (int j = len - 1; j >= i; j--)
{
if (a[j] < a[j - 1])
{
swap(a[j],a[j-1]);
}
}
}
for (int i = 0; i < len; i++)
{
cout << a[i] << " ";
}
cout << "\n";
}
//-------------------------------------------------
//直接插入排序
void Insert_Sort(int *a, int len)
{
for (int i = 1; i < len; i++)
{
if (a[i] < a[i - 1])
{
int t = a[i];
int j;
for (j = i-1; j >= 0 && a[j]>t; j--)
{
a[j + 1] = a[j];
}
a[j + 1] = t;
}
}
for (int i = 0; i < len; i++)
{
cout << a[i] << " ";
}
cout << "\n";
}
//-------------------------------------------------
//快速排序
int Partition(int *a,int s, int e)
{
int x = a[e];
int start = s - 1;
for (int i = s; i < e; i++)
{
if (a[i] <= x)
{
start++;
swap(a[start],a[i]);
}
}
swap(a[start+1],a[e]);
return start + 1;
}
void Quick_Sort(int *a, int s, int e)
{
if (s < e)
{
int q = Partition(a,s,e);
Quick_Sort(a,s,q-1);
Quick_Sort(a,q+1,e);
}
}
//随机版快排
int Random(int m, int n)
{
return (int)((double)rand()/(double)RAND_MAX*(n-m+1)+m);
}
int Rand_Partition(int *a, int s, int e)
{
int end = Random(s,e);
swap(a[end],a[e]);
return Partition(a, s, e);
}
void Rand_QuickSort(int *a, int s, int e)
{
if (s < e)
{
int q = Rand_Partition(a,s,e);
Rand_QuickSort(a,s,q-1);
Rand_Partition(a,q+1,e);
}
}
//基数排序
//1.数值型
int getDigit(int num, int index)
{
int mod=1;
while (index)
{
mod *= 10;
index--;
}
int div = mod / 10;
return num%mod / div;
}
void Count_Sort(int *A, int *B, int len, int k, int d)
{
int count = k + 1;
int *C = new int[count];
for (int i = 0; i < count; i++)
{
C[i] = 0;
}
for (int i = 0; i < len; i++)
{
C[getDigit(A[i], d)] = C[getDigit(A[i], d)] + 1;
}
for (int i = 1; i < count; i++)
{
C[i] = C[i] + C[i - 1];
}
for (int i = len - 1; i >= 0; i--)
{
B[C[getDigit(A[i], d)] - 1] = A[i];
C[getDigit(A[i], d)] -= 1;
}
}
void Radix_Sort(int *A, int d, int len)
{
for (int i = 1; i <= d; i++)
{
int *B = new int[len + 1];
Count_Sort(A,B,len,10,i);
for (int i = 0; i < len; i++)
{
A[i] = B[i];
}
delete[]B;
}
}
//2.字母型
int getAlpha(string A, int index)
{
return (A.at(A.length() - index) - 'a');
}
void Count_SortAlpha(string *A, string *B, int len,char k, int d)
{
int count = (k-'a'+1);
int *C = new int[count];
for (int i = 0; i < count; i++)
{
C[i] = 0;
}
for (int i = 0; i <len; i++)
{
C[getAlpha(A[i], d)] = C[getAlpha(A[i], d)] + 1;
}
for (int i = 1; i < count; i++)
{
C[i] = C[i] + C[i - 1];
}
for (int i = len-1; i>=0; i--)
{
B[C[getAlpha(A[i], d)] - 1] = A[i];
C[getAlpha(A[i], d)] -= 1;
}
}
void Radix_SortAlpha(string *A, int d, int len)
{
for (int i = 1; i <= d; i++)
{
string *B = new string[len];
Count_SortAlpha(A,B,len,'z',i);
for (int i = 0; i < len; i++)
{
A[i] = B[i];
}
delete[]B;
}
}
int main()
{
int a = 10;
int b = 15;
cout <<"gcd="<< gcd(a, b) << endl;
cout << "---------------------------------"<<endl;
//---------------------------------
string T = "abababbc";
string P = "ab";
Kmp_Matcher(T,P);
cout << "---------------------------------" << endl;
//---------------------------------
Perm_Print("abc");
cout << "---------------------------------" << endl;
//---------------------------------
int PP[] = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };
int sz = sizeof P / sizeof P[0];
cout<<Cut_Rod(PP, 4)<<endl;
cout << "---------------------------------" << endl;
//---------------------------------
cout << Print_Memoized_Cut_Rod(PP,4)<<endl;
cout << "---------------------------------" << endl;
//---------------------------------
cout << BottomUp_Cut_Rod(PP, 4) << endl;
cout << "---------------------------------" << endl;
//---------------------------------
cout << Print_BP_Cut_Rod(PP, 7) << endl;
cout << "---------------------------------" << endl;
//---------------------------------
int arr[] = { 1, 3, 2, 5,4 };
int size = sizeof arr / sizeof arr[0];
//SimpleSelectSort(arr,size);
//cout << "---------------------------------" << endl;
//---------------------------------
//Bubble_Sort(arr, size);
//cout << "---------------------------------" << endl;
//---------------------------------
//Insert_Sort(arr, size);
//cout << "---------------------------------" << endl;
//---------------------------------
//Quick_Sort(arr, 0,size-1);
//for (int i = 0; i < size; i++)
//{
// cout << arr[i] << " ";
//}
//cout << "\n";
//cout << "---------------------------------" << endl;
//---------------------------------
//srand((int)time(0));
//Rand_QuickSort(arr, 0, size - 1);
//for (int i = 0; i < size; i++)
//{
// cout << arr[i] << " ";
//}
//cout << "\n";
//cout << "---------------------------------" << endl;
//---------------------------------
int A[] = { 329, 457, 657, 839, 436, 720, 355, 0, 12, 15, 105 };
int N = sizeof A / sizeof A[0];
Radix_Sort(A, 3, N);
for (int i = 0; i<N; i++)
{
cout << A[i] << " ";
}
cout << "\n";
cout << "---------------------------------" << endl;
string Alpha[] = { "cow", "sea", "rug", "row", "mob", "box", "tab", "bar", "tar", "dig", "big", "tea", "now", "fox" };
N = sizeof Alpha / sizeof Alpha[0];
Radix_SortAlpha(Alpha, 3, N);
for (int i = 0; i < N; i++)
{
cout << Alpha[i] << " ";
}
cout << "\n";
cout << "---------------------------------" << endl;
}