算法设计与分析:C++实现大整数加减法、大整数乘法、最近点对问题(通俗易懂,上手快)

话不多说,直接上代码!!!

一、大整数加减法

#include <iostream>
#include <string>
using namespace std;

//输入两个字符串形式的非负大整数x和y,计算它们的和或差
class Solveaddsub
{
    public:
    string add(string x, string y)  //大整数加法
    {
           //当x位数大于y时
        if(x.size() < y.size())
       {
           swap(x,y);  //交换x,y
       }
        string ret(x.size() + 1, '0');
        char step = 0;
        for(int il = x.size() - 1, ir = y.size() - 1; il >= 0; il--, ir--)
        {
            char ch = x[il] - '0' + step;
            if(ir >= 0)
            {
                ch += y[ir] - '0';
            }
            step = 0;
            if(ch >= 10)
            {
                step = 1;
                ch -= 10;
            }
            ret[il + 1] += ch;
        }
        if(step == 1)
        {
            ret[0] += step;
        }
        else
        {
            ret.erase(ret.begin());
        }
        return ret;
    }

    string sub(string x, string y)   // 大整数减法
    {
             //当x位数小于y时
        if(x.size() < y.size())
        {
           swap(x,y);  //交换x,y
        }
        string ret(x.size(), '0');
        char step = 0;
        for(int il = x.size() - 1, ir = y.size() - 1; il >= 0; il--, ir--)
        {
            char ch = x[il] - '0' - step;
            step = 0;
            if(ir >= 0)
            {
				if((x[il] - '0') < (y[ir] - '0'))
                {
                    step = 1;
                    ch += 10;
                }
                ch -= y[ir] - '0';
            }
            if(ir < 0 && ch < 0)
            {
                step = 1;
                ch += 10;
            }
            ret[il] += ch;
        }
        if(step == 1)
        {
            ret[0] -= 1;
        }
        while (ret[0] == '0')
        {
            ret.erase(ret.begin());
        }
        return ret;
    }
};
int main()
{
    string a,b,m;
    Solveaddsub s;
    cin >> a >> m >> b;  //其中m是+或-,a和b是两个大整数
    if(m == "+")
      cout << "结果:" << s.add(a,b) << endl;
    else if(m == "-")
    {
        if(a > b)
        cout << "结果:" << s.sub(a,b) << endl;
        else
        cout << "结果:" << s.sub(b,a) << endl;
    }
    else
       cout << "error";
    return 0;
}

二、大整数乘法(C语言实现)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char a[256], b[256];    //把大整数a和b用字符型的数组来定义
int anum[256], bnum[256], ab[5000];   //anum为大整数a的数字型,bnum为大整数b的数字型,ab为它们的乘积数字型;
int main()
{
    gets(a); //得到大整数a
    gets(b);    //得到大整数b
    int len1 = strlen(a);    //获取大整数a的长度
    int len2 = strlen(b);    //获取大整数b的长度
    int j;
    int i = 0;
    for(j = len1 - 1; j >= 0; j--)
    {
        anum[i] = a[j] - '0';   //获取大整数a中第j位上的数字,作为anum数组的第i+1个
        i++;
    }
    i = 0;
    for(j = len2 - 1;j >= 0; j--)
    {
        bnum[i] = b[j] - '0';    //获取大整数b中第j位上的数字,作为bnum数组的第i+1个
        i++;
    }
    for(i=0;i<len2;i++)
    {
        for(j=0;j<len1;j++)
            ab[i+j]+=anum[i] * bnum[j];  //相乘算结果
    }
    for(i = 0;i < 200;i ++)
    {
    	//处理相加大于10的情况
        if(ab[i] >= 10)
        {
            ab[i+1]=ab[i+1]+ab[i]/10;
            ab[i]=ab[i]%10;
        }
    }
    printf("结果:");
    int flag;   //设置一个Flag,从ab[]的较大的下标位开始循环,遇到非0的数才打印,实现去除前导零的步骤。
    flag = 0;
	for(i = 200; i >= 0; i --)
		if(flag)
			printf("%d", ab[i]);
		else if(ab[i]) {
			printf("%d", ab[i]);
			flag = 1;
		}
	if(!flag )
		printf("0");
	return 0;
}

 三、最近点对问题

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<vector>
#include<climits>
using namespace std;

typedef struct node{  //为Point容器定义一个叫node的结构体,用来存放每个点对的横坐标和纵坐标
	int x,y;
}Point;

vector <Point> T(300000); // 声明一个叫Point的且容量为300000的动态数组(容器)

double dist(Point p1, Point p2)   //p1,p2是两个点对,求它们之间的距离
{
	return sqrt((double)(p1.x - p2.x)*(p1.x - p2.x)+(double)(p1.y - p2.y)*(p1.y - p2.y));
}

bool comparex(Point a,Point b) //sort()里点对横坐标的比较函数,对x进行升序排序,若x相同则依照y进行升序排序
{
	if (a.x == b.x)
		return a.y < b.y;
	return a.x < b.x;
}

bool comparey(Point a,Point b)    //sort()里点对纵坐标的比较函数,对y进行排序
{
	return a.y < b.y;
}

double Merge(vector<Point>&P, int low, int mid, int high, double d)   //分治法求最近点对,其中参数是点对的数组,low,high两个指针用来标记
{
	int i,j,k=0;
	for (i = low; i <= high; i++){
		if(fabs(1.0 * P[mid].x - 1.0 * P[i].x) < d)
			T[k++] = P[i];   // k是T的大小
	}
	sort(T.begin(), T.begin() + k, comparey);  //进行排序
	double mind = d;
	for (i = 0; i < k - 1; i++){               //边界是k-1
		for (j = i + 1; j < min(i + 7, k); j++){
			if (dist(T[i], T[j]) < mind)
				mind = dist(T[i], T[j]);
		}
	}
	return mind;
}

double mergesolution(vector<Point>&P, int low, int high) //合并
{
	if (low >= high) return (double)INT_MAX;// 如果自己与自己的距离最近,那直接输出距离为0.00
	if (low + 1 == high) // 这两点中间没有任何点,所以直接求距离
		return dist(P[low], P[high]);
	int mid = (high + low) / 2;    //求出mid
	double d = min(mergesolution(P, low, mid), mergesolution(P, mid + 1, high));// 分别获得两分区中最近点对距离,并取这两个距离之中的较小值
	return Merge(P, low, mid, high, d);
}

int main(){
	int n,i;
	scanf("%d",&n);     //输入点对数
	vector <Point> P(n); //定义一个在Point容器里面叫P的数组来储存x和y
	for (i = 0; i < n; i++)
		scanf("%d,%d", &P[i].x, &P[i].y);  //调用结构体来输入x,y,其中x是点对的横坐标,y是点对的纵坐标
	sort(P.begin(), P.begin() + n, comparex); //开始进行分治,其中P.begin()用来返回P数组第一个数的地址
	printf("%.2lf\n", mergesolution(P, 0, n - 1)); //输出最近点对距离,且为两位小数
}

以上就是本次分享的全部内容啦!希望大家能多多点赞收藏啊!!! 

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
### 回答1: 大整数的加减乘除运算是算法设计与分析中的一个重要问题。对于大整数的加减乘除运算,需要设计高效的算法来处理。其中,加法和减法可以采用类似于小学数学中的竖式计算方法,乘法可以采用类似于小学数学中的乘法计算方法,而除法则需要采用更为复杂的算法,如长除法或牛顿迭代法等。在算法设计与分析中,需要考虑算法的时间复杂度和空间复杂度,以及算法的正确性和稳定性等问题。同时,还需要考虑算法的实际应用场景,如密码学、计算机图形学、计算机视觉等领域,以便选择合适的算法。 ### 回答2: 随着计算机科学和技术的不断发展,大整数计算逐渐成为计算机科学中的一个重要问题。 在日常生活中,我们经常需要处理大数的加减乘除,例如:财务管理、密码学、科学计算等。这些雄厚的数字往往需要通过一些算法进行高效的计算,这就需要一些针对大整数算法设计与分析大整数加法:大整数加法其实就是小学数学中的竖式加法。我们可以先将两个大数的最低位相加,将结果的个位保存下来,然后将得到的进位加到下一位的计算中,直到所有位数都加完。 大整数减法:大整数减法可以通过加上相反数来实现。具体来说,我们将被减数和减数的位数对齐,然后按位进行减法操作。需要注意的是,如果被减数小于减数,则需要借位。 大整数乘法大整数乘法一般采用传统的乘法规则:将两个数的每一位相乘,并保持结果在正确的位上。需要注意的是,乘法可以通过使用一些技巧来加速计算,例如:Karatsuba算法和分治法。 大整数除法:大整数除法一般采用长除法或者二分法进行。长除法与小学时候学习的是一样的,通过将被除数的一位一位与除数对齐,然后逐个相除。二分法则通过不断地将除数倍增来加速计算。 总而言之,针对大整数的加减乘除运算需要使用一些高效的算法来进行计算。这些算法的设计和分析将会涉及到大量的数学原理和计算机科学的知识。同时,算法实现也需要考虑到程序的效率和正确性。 ### 回答3: 随着计算机科学的发展,数字运算一直是算法设计和分析中应该掌握的基础部分。除了基本的整数运算,对于大整数的加、减、乘、除等运算也非常重要。大整数的运算是指超过计算机原始字长的整数的运算。 对于大整数的加、减、乘、除,我们需要使用不同的算法来执行。以下是针对大整数的四种运算的算法简介: 大整数加法:大整数加法的基本思路很简单:将大整数分割成同样长度的数字部分并对相应的数字部分执行加法运算。如果有进位,进位值将被带入下一位的计算中。最终结果是一个大整数大整数减法:大整数减法比加法稍微复杂一些。常用的方法是将 位权相同的两个位数相减。如果被减数小于减数,则需要进行借位。借位意味着从高位借一位,同时在当前位减去10。如果需要多次借位,就需要连续地对更高的位进行借位操作。 大整数乘法:用笔和纸做乘法的方法是讲算术方法还原成使用乘法表,那在算法设计中我们就可以使用竖式乘法。在这种方法中,使用被乘数和乘数的每一位进行部分乘法计算,并将结果加起来。这种方法可以极大地降低计算量。 大整数除法:除法在大整数中是最棘手的运算。可以将从左到右的数字逐位与除数相除。如果它小于除数,则将下一位的数字添加到被除数中。具体的除数和被除数都需要调整,以确保它们具有相同的数字长度。最终结果是商和余数。 总之,算法设计和分析中大整数的加、减、乘、除是非常重要的部分。在实际项目中,大整数的四种运算也经常出现。所以我们必须理解这些算法并熟练掌握它们。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寥若晨星666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值