有关高精度和排序的回顾

注:本文为回顾,所以仅会记录本人认为的难点与分析


高精度

高精度乘法

乘法可用竖式计算,\(a,b\)为因数,\(c\)为积
列出竖式后,可以发现,\(c\)的值与上一位的进位\(x\)\(a_i,b_j\)的积和进行几次计算后\(c\)的值有关,所以我们得到\(c_{i+j-1}=a_i \times b_j + x + c_{i+j-1},x=c_{i+j-1} \div 10,c_{i+j-1} \% =10\);
由此,我们可以得到以下程序:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int lena,lenb,lenc,a[201],b[201],c[40101],x;
char al[201],bl[201];
int main(){
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	scanf("%s",&al);
	scanf("%s",&bl);
	lena = strlen(al);
	lenb = strlen(bl);
	for (int i = 0;i <= lena - 1;i ++)
	  a[lena - i] = al[i] - '0';
	for (int i = 0;i <= lenb - 1;i ++)
	  b[lenb - i] = bl[i] - '0';
	for (int i = 1;i <= lena;i ++){
		x = 0;
		for (int j = 1;j <= lenb;j ++){
			c[i + j - 1] = c[i + j - 1] + x + a[i] * b[j];
			x = c[i + j - 1] / 10;
			c[i + j - 1] %= 10;
		}
		c[i + lenb] = x;
	}
	lenc = lena + lenb;
	while (c[lenc] == 0 && lenc > 1)
	  lenc --;
	for (int i = lenc;i >= 1;i --)
	  cout << c[i];
	return 0;
} 

高精度除法

我们利用减法代替除法,一次次的进行相减,直到无法继续减

比较

这里主要用于两数相减时,比较两者大小,若相等,返回零即可,若被减数\(a\)大于减数\(b\),返回1,继续运算,若小于\(b\),则返回-1,表示已不能继续减;

int compare(int a[],int b[]){
	if (a[0] < b[0])  return -1;
	if (a[0] > b[0])  return 1;
	for (int i = a[0];i > 0;i --){
		if (a[i] > b[i])  return 1;
		if (b[i] > a[i])  return -1;
	}
	return 0;
}

相减

先进行判断,是否可以相减,再进行运算,具体步骤与高精度减法类似

void jian(int a[],int b[]){
	int f,i;
	f = compare(a,b);
	if (f == 0){
		a[0] = 0;
		return;
	}
	if (f == 1){
		for (i = 1;i <= a[0];i ++){
			if (a[i] < b[i]){
				a[i + 1] --;
				a[i] += 10;
			}
			a[i] -= b[i];
		}
		while (a[a[0]] == 0 && a[0] > 0)   //去除前导零
		  a[0] --;
	}
}

复制

由于我们在运算中并不是对两个高精数直接相减,而是分段进行,所以需要一个复制函数

void copy(int p[],int q[],int num){
	for (int i = 1;i <= p[0];i ++)
	  q[i + num - 1] = p[i];       //复制,可保留相应位数
	q[0] = p[0] + num - 1;
}

除法

我们在上面讲过了,除法用减法进行代替,所以这里的本质就是一次次循环相减,每减去一次,相应位上的\(c\)自加一;

void chu(int a[],int b[],int c[]){
	int i,tem[101];
	c[0] = a[0] - b[0] + 1;
	for (i = c[0];i > 0;i --){
		memset(tem,0,sizeof(tem));
		copy(b,tem,i);//对需减去的数进行复制
		while (compare(a,tem) >= 0){
			c[i] ++;//每进行一次,c+1
			jian(a,tem);//运行减法
		}
	}
	while (c[0] > 0 && c[c[0]] == 0)
	  c[0] --;//去除前导零
}

完整代码

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int a[101],b[101],c[101];
void init(int i[]){
	string s;
	cin >> s;
	i[0] = s.length();
	for (int j = 1;j <= i[0];j ++)
	  i[j] = s[i[0] - j] - '0';
}
int compare(int a[],int b[]){
	if (a[0] < b[0])  return -1;
	if (a[0] > b[0])  return 1;
	for (int i = a[0];i > 0;i --){
		if (a[i] > b[i])  return 1;
		if (b[i] > a[i])  return -1;
	}
	return 0;
}
void jian(int a[],int b[]){
	int f,i;
	f = compare(a,b);
	if (f == 0){
		a[0] = 0;
		return;
	}
	if (f == 1){
		for (i = 1;i <= a[0];i ++){
			if (a[i] < b[i]){
				a[i + 1] --;
				a[i] += 10;
			}
			a[i] -= b[i];
		}
		while (a[a[0]] == 0 && a[0] > 0)
		  a[0] --;
	}
}
void copy(int p[],int q[],int num){
	for (int i = 1;i <= p[0];i ++)
	  q[i + num - 1] = p[i];
	q[0] = p[0] + num - 1;
}
void chu(int a[],int b[],int c[]){
	int i,tem[101];
	c[0] = a[0] - b[0] + 1;
	for (i = c[0];i > 0;i --){
		memset(tem,0,sizeof(tem));
		copy(b,tem,i);
		while (compare(a,tem) >= 0){
			c[i] ++;
			jian(a,tem);
		}
	}
	while (c[0] > 0 && c[c[0]] == 0)
	  c[0] --;
}
void print(int p[]){
	if (p[0] == 0){
		cout << 0 << endl;
		return;
	}
	for (int i = p[0];i > 0;i --)
	  cout << p[i];
	cout << endl;
}
int main() {
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	init(a);
	init(b);
	chu(a,b,c);
	print(c);
	print(a);
	return 0;
}

对应题目

高精乘:戳这里
高精除:戳这里


排序

这里主要讲解快速排序

快排的主要思想是二分法,通过对数据进行二分提高速度,时间复杂度为\(O(n\log_{2}{n})\),不过是一种不稳定的排序

#include <iostream>
#include <algorithm> 
using namespace std;
void quicksort (int [], int, int);
int partition (int [], int, int);
int main()
{
    const int SIZE = 10;
    int array[SIZE] = {17, 53, 9, 2, 30, 1, 82, 64, 26, 5};
    for (int k = 0; k < SIZE; k++)
        cout << array[k] << " ";
    cout << endl;
    quicksort (array, 0, SIZE-1);
    for (int k = 0; k < SIZE; k++)
        cout << array[k] << " ";
    cout << endl;
    return 0;
}
void quicksort (int arr[], int start, int end)
{
    if (start < end)
    {
        int p = partition(arr, start, end);
        quicksort(arr, start, p - 1);
        quicksort(arr, p + 1, end);
    }
}
int partition(int arr[], int start, int end)
{
    int pivotValue = arr[start];
    int pivotPosition = start;
    for (int pos = start + 1; pos <= end; pos++)
    {
        if (arr[pos] < pivotValue)
        {
            swap(arr[pivotPosition + 1], arr[pos]);
            swap(arr[pivotPosition], arr[pivotPosition + 1]);
            pivotPosition ++;
        }
    }
    return pivotPosition;
}

更新日志

  • \(2020.5.9\) 完成编辑

日后优化会持续跟进

posted @ 2020-05-09 21:12  Dfkuaid  阅读(232)  评论(0编辑  收藏  举报