算法设计与分析作业

简介: 这篇文章是关于算法设计与分析的作业,其中包含了两个算法实现:一个是使用分治算法实现的十进制大整数相乘(包括加法、减法和乘法函数),并进行了正确性和健壮性测试;另一个是使用快速排序思想实现的分治查找第K小元素的程序,并分析了其平均和最坏时间复杂度。

算法设计与分析作业

题⽬1 - 使⽤分治算法实现⼗进制⼤整数相乘

一、要求

  1. 给出代码(了解markdown格式如何插入⼀段代码)
  2. 复杂度为 。n为整数的位数。
  3. ⾄少包含add(a,b) minus(a,b) multiply(a,b)三个函数。
  4. ⾃⾏设计测试样例,测试你的程序的正确性和健壮性。给出测试结果。

二、程序如下

#include <iostream>
#include <string.h>
#include<algorithm>
using namespace std;

string multi(string number_a, string number_b) {
    if(number_a=="0"||number_b=="0")return "0";
    int flag1=1;
    int len_a = number_a.length(); //计算长度
    int len_b = number_b.length();

    int* num_arr = new int[len_a+len_b];
    memset(num_arr, 0, sizeof(int)*(len_a+len_b)); //置0

    for (int i=len_a-1; i>=0; --i) { //计算每一位
        for (int j=len_b-1; j>=0; --j) {
        num_arr[i+j+1] += (number_b[j]-'0')*(number_a[i]-'0');
        }
    }

    for (int i=len_a+len_b-1; i>=0; --i) { //进位
        if (num_arr[i] >= 10) {
            num_arr[i-1] += num_arr[i]/10;
            num_arr[i] %= 10;
        }
    }
    string result;

    for( int i=0; i<(len_a+len_b); ++i){
        if(num_arr[i]==0&&flag1)continue;
          else flag1=0;
        result += (char)(((int)'0')+num_arr[i]);
    }

    delete[] num_arr;

    return result;
}
int compareNumber(string a,string b)
{
    if(a.length()>b.length())return 1;
    else if(a.length()<b.length())return -1;
    else
    {
        if(a>b)return 1;
        else if(a<b)return -1;
        else return 0;
    }
}
string add(string number_a, string number_b) {

    string result;
    int i;
    if(compareNumber(number_a,number_b)==-1)swap(number_a,number_b);
    int len_a = number_a.length(); //计算长度
    int len_b = number_b.length();

    int* num_arr = new int[len_a+1];
    memset(num_arr, 0, sizeof(num_arr)); //置0

    for (i=1; i<=len_b; i++) { //计算每一位
        num_arr[len_a-i+1] = (number_b[len_b-i]-'0')+(number_a[len_a-i]-'0');
    }
    for(;i<=len_a;i++)
    {
        num_arr[len_a-i+1]=number_a[len_a-i]-'0';
    }
    for (int i=len_a; i>=0; --i) { //进位并转换成字符串
        if (num_arr[i] >= 10) {
            num_arr[i-1] += 1;
            num_arr[i] %= 10;
        }
        if(i==0&&num_arr[0]==0)continue;
        result = (char)(((int)'0')+num_arr[i])+result;
    }

    delete[] num_arr;
    return result;
}
string Minus(string number_a, string number_b) {

    string result;
    int i,flag=0,flag1=1;
    if(compareNumber(number_a,number_b)==-1)
    {
        swap(number_a,number_b);
        flag=1;
    }
    if(number_a==number_b)return "0";
    int len_a = number_a.length(); //计算长度
    int len_b = number_b.length();

    int* num_arr = new int[len_a+1];
    memset(num_arr, 0, sizeof(num_arr)); //置0

    for (i=1; i<=len_b; i++) { //计算每一位
        num_arr[len_a-i+1] = (number_a[len_a-i]-'0')-(number_b[len_b-i]-'0');
    }
    for(;i<=len_a;i++)
    {
        num_arr[len_a-i+1]=number_a[len_a-i]-'0';
    }
    for (int i=len_a; i>=1; --i) { //进位并
        if (num_arr[i] < 0) {
            num_arr[i-1]--;
            num_arr[i] += 10;
        }
    }
        for (int i=0; i<=len_a; i++) { //转换成字符串
          if(num_arr[i]==0&&flag1)continue;
          else flag1=0;
        result += (char)(((int)'0')+num_arr[i]);
    }
    if(flag)result="-"+result;
    delete[] num_arr;

    return result;
}
void addzone(string &number,int num)
{
    while(num--)
    {
        number+="0";
    }
}
string multi1(string number_a,string number_b)
{
    string a0,a1,b1,b0,c0,c1,c2,a2,b2;
    int half;
    int len_a=number_a.size();
    int len_b=number_b.size();
    if(len_a<=2||len_b<=2)return multi(number_a,number_b);
    if(len_a<len_b)return multi1(number_b,number_a);
    if(len_a==0||len_b==0)return "";
    if(len_a/2>=len_b)half=len_b-1;
    else half=len_a/2;
    a1=number_a.substr(0,len_a-half);
    a0=number_a.substr(len_a-half,half);
    b1=number_b.substr(0,len_b-half);
    b0=number_b.substr(len_b-half,half);
     c1=multi1(a1,b1);
     c0=multi1(a0,b0);
     a2=add(a1,a0);
     b2=add(b0,b1);

     c2=multi1(a2,b2);
     c2=Minus(c2,c1);
     c2=Minus(c2,c0);
    addzone(c1,half*2);
    addzone(c2,half);

    string result=add(add(c1,c0),c2);
    return result;
}
bool checkNumberValid(string a,string b)
{
    for(int i=0;i<a.length();i++)
    {
        if(i==0&&(a[i]<=57&&a[i]>=48||a[i]==45))continue;
        if(a[i]>57||a[i]<48)return false;
    }
        for(int i=0;i<b.length();i++)
    {
        if(i==0&&(b[i]<=57&&b[i]>=48||b[i]==45))continue;
        if(b[i]>57||b[i]<48)return false;
    }
    return true;
}
int main(void){

    string number_a,number_b;
    int index=1;
    while(cin>>number_a>>number_b)
    {
        cout<<"第"<<index++<<"次"<<endl;
        if(!checkNumberValid(number_a,number_b))
        {
            cout<<"Please input the Valid Number"<<endl<<endl;
            continue;
        }
       // cout << number_a << " * " << number_b << " = " <<multi(number_a, number_b) <<endl;
        cout<<number_a<<"+"<<number_b<<"="<<add(number_a,number_b)<<endl;
        cout<<number_a<<"-"<<number_b<<"="<<Minus(number_a,number_b)<<endl;
        cout << number_a << " * " << number_b << " = " <<multi1(number_a, number_b) <<endl;
        cout<<endl;
    }
    return 0;
}
测试样例:

55513513133535351 3513535133135133
535 123
153153 253
25 0
0 135513
22222 22222
2a 122
2153 222c
5555555555555555555555555555555555555555555555555 44444 555555
111111111111111111111111111111111888888888888888888888888888888888888888888

三、完成情况如下

任务0:给出代码。完成
任务1 :复杂度为 。n为整数的位数。multi1采用Karatsuba算法实现乘法的优化。完成
2. ⾄少包含add(a,b) minus(a,b) multiply(a,b)三个函数。完成
3. ⾃⾏设计测试样例,测试你的程序的正确性和健壮性。给出测试结果。

a.正确性判断

我拿出科学计算器测试了程序的加法,减法,乘法与程序运行结果一致。
在这里插入图片描述

b.健壮性

在这里插入图片描述
在这里插入图片描述

  • 1.当输入的字符串里面含有非法字符会提示:"Please input the Valid Number 并等待下一次输出。
  • 2.同时该算法也支持负数计算
  • 3.自动去除多余的零

题⽬2 - ⽤快速排序思想写⼀个分治的查找第K⼩元素的程序

一、要求

  1. 给出代码
  2. 给出证明代码可以正确运⾏的截图
  3. 分析最坏复杂度和平均复杂

二、程序

#include<iostream>
#include<stdlib.h>
using namespace std;
int a[101],n;
void quickFind(int left,int right,int k)
{
    int i,j,t,temp;
    if(left>right)return;
    i=left,j=right;
    while(i!=j)
    {
        //顺序很重要,要先从右往左找
        while(a[j]>=a[left]&&i<j)j--;
        //从左往右找
        while(a[i]<=a[left]&&i<j)i++;
        //找到后交换两个数的位置
        if(i<j)swap(a[i],a[j]);

    }
    //最后将基准数归位

    swap(a[i],a[left]);

    if(k==i)cout<<a[k]<<endl;
    else if(k<i)quickFind(left,i-1,k);//处理左边
    else quickFind(i+1,right,k);//处理右边

}
int main()
{
    int k;
    while(1)
    {
    cout<<"请输入数组的大小:"<<endl;
    cin>>n;
    cout<<"请输入"<<n<<"个实数"<<endl;
    for(int i=1;i<=n;i++)cin>>a[i];
    cout<<"请输入一个整数表示要求的第k小的:"<<endl;
    cin>>k;
    if(k<1||k>n)
    {
        cout<<"请输入有效数字"<<endl;
        continue;
    }
    cout<<"第"<<k<<"小的数字为:";
    quickFind(1,n,k);

    system("pause");
    system("CLS");
    }
    return 0;
}

样例与输出

样例

11
153351 131 513 135 15 35 1351 3513 15353 11 22
4

输出

在这里插入图片描述

这个算法的平均时间复杂度是O ( n ) 的,每一次快排为n,在有序下平均c次即可找到(c为常量),但在最坏情况下的时间复杂度是O ( n 2 )比如:9 8 7 6 5 4 3 2 1,求第9大。

相关文章
|
2月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
76 4
|
17天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
46 1
|
1月前
|
算法 调度
基于遗传模拟退火混合优化算法的车间作业最优调度matlab仿真,输出甘特图
车间作业调度问题(JSSP)通过遗传算法(GA)和模拟退火算法(SA)优化多个作业在并行工作中心上的加工顺序和时间,以最小化总完成时间和机器闲置时间。MATLAB2022a版本运行测试,展示了有效性和可行性。核心程序采用作业列表表示法,结合遗传操作和模拟退火过程,提高算法性能。
|
2月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
2月前
|
算法
PID算法原理分析
【10月更文挑战第12天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。
|
3月前
|
算法 搜索推荐 开发者
别再让复杂度拖你后腿!Python 算法设计与分析实战,教你如何精准评估与优化!
在 Python 编程中,算法的性能至关重要。本文将带您深入了解算法复杂度的概念,包括时间复杂度和空间复杂度。通过具体的例子,如冒泡排序算法 (`O(n^2)` 时间复杂度,`O(1)` 空间复杂度),我们将展示如何评估算法的性能。同时,我们还会介绍如何优化算法,例如使用 Python 的内置函数 `max` 来提高查找最大值的效率,或利用哈希表将查找时间从 `O(n)` 降至 `O(1)`。此外,还将介绍使用 `timeit` 模块等工具来评估算法性能的方法。通过不断实践,您将能更高效地优化 Python 程序。
67 4
|
3月前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
54 1
|
2月前
|
算法
PID算法原理分析及优化
【10月更文挑战第6天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。
|
2月前
|
机器学习/深度学习 算法 数据处理
EM算法对人脸数据降维(机器学习作业06)
本文介绍了使用EM算法对人脸数据进行降维的机器学习作业。首先通过加载ORL人脸数据库,然后分别应用SVD_PCA、MLE_PCA及EM_PCA三种方法实现数据降维,并输出降维后的数据形状。此作业展示了不同PCA变种在人脸数据处理中的应用效果。
38 0
|
3月前
|
算法 调度
作业调度算法_先来先服务算法_短作业优先算法_高响应比优先算法
本文介绍了作业调度算法,包括先来先服务(FCFS)、短进程优先(SJF)和高响应比优先(HRRN)算法。通过分析进程的到达时间和所需CPU服务时间,计算进程的开始时间、完成时间、平均周转时间和平均带权周转时间,以评估不同算法的性能。FCFS适合长作业,SJF适合短作业,而HRRN则综合了两者的优点。
118 12