首页 > 编程语言 >【数据结构·队列】链队列(带头结点)模板简单应用算法设计:长整数加法计算

【数据结构·队列】链队列(带头结点)模板简单应用算法设计:长整数加法计算

时间:2024-06-09 15:59:25浏览次数:32  
标签:结点 return string 队列 int result str front 数据结构

目的:使用C++模板设计链队列的抽象数据类型(ADT)。并在此基础上,使用链队列ADT的基本操作,设计并实现简单应用的算法设计。

内容:(1)请参照单链表的ADT模板,设计链队列的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的单链表ADT原型文件,自行设计链队列的ADT。)

注意:链队列带头结点。

(2)ADT的简单应用:使用该ADT设计并实现应用链队列的算法设计。

应用:假设2个任意长度的整数x、y分别由带头结点的链队列A和B存储,现要求设计一个算法,实现任意长的整数进行加法运算。

参考函数原型:

template<class ElemType>

void Long_Int_Add( LinkQueue<ElemType> &A, LinkQueue<ElemType> &B, string &result, string &A_str, string &B_str ); //result 计算结果字符串

辅助函数原型:

(1)从长整数的低位开始拆分(4位为一组,即不超过9999的非负整数),依次入队到链队列中;头结点的数据域存放正负数标志(正数或0:1,负数:-1)。

template<class ElemType> 

void Input_Int_Division( LinkQueue<ElemType> &A, string &str );

(2)计算结果中间位格式控制

string Int_String( int result );

(3)两个长整数的绝对值大小比较(x>y 返回值为1;x<y 返回值为2;x=y 返回值为0;)

template<class ElemType>

int Two_LongNum_Compare( string &A_str, string &B_str );

输入说明

第一行:长整数x

第二行:长整数y

输出说明

第一行:格式化后的长整数x(从低位到高位每4位用‘,’分开)

第二行:格式化后的长整数y(从低位到高位每4位用‘,’分开)

第三行:空行

第四行:格式化后的计算结果(从低位到高位每4位用‘,’分开)

输入范例

-53456467576846547658679870988098
435643754856985679

输出范例

-5345,6467,5768,4654,7658,6798,7098,8098
43,5643,7548,5698,5679

-5345,6467,5768,4611,2014,9250,1400,2419

AC代码

#include<iostream>
#include <sstream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<vector>
#include <climits>
#define MAX_SIZE 100
using namespace std;
template<class ElemType>
struct LinkQueueNode
{
    ElemType data;
    LinkQueueNode<ElemType> *next;
    LinkQueueNode(LinkQueueNode<ElemType> *ptr = NULL){next = ptr;}
    LinkQueueNode(const ElemType &item, LinkQueueNode<ElemType> *ptr = NULL)
    {
        next = ptr;
        data = item;
    }
};
template<class ElemType>
class LinkQueue
{
    private:
      LinkQueueNode<ElemType> *front;
      LinkQueueNode<ElemType> *rear;
      int length;
    public:
      LinkQueue()
      {
          front=rear=new LinkQueueNode<ElemType>();
          front->next=NULL;
          length=0;
      }
      int QueueLength() const{ return length;}
      bool QueueisEmpty() const;
      bool deQueue( ElemType &e )
      {
          if(QueueisEmpty())return false;
          auto p=front->next;
          e=p->data;
          front->next=p->next;
          if(rear==p)rear=front;
          delete p;
          length--;
          return true;
      }
       bool enQueue( ElemType e )
       {
           auto p=new LinkQueueNode<ElemType>(e);
           rear->next=p;
           rear=p;
           length++;
           return true;
       }
       void clear()
       {
           rear->next=NULL;
           front=rear;
           length=0;
       }
       void change_front(int da)
       {
           front->data=da;
       }
       int front_data(){return front->data;}
       LinkQueueNode<ElemType> * getfront(){return front;}
       LinkQueueNode<ElemType> * getrear(){return rear;}
};
template<class ElemType>
void niprint(LinkQueue<ElemType> &A,LinkQueueNode<ElemType> *p)
       {

           if(p->next==NULL){cout<<p->data<<',';return ;}
           niprint(A,p->next);
           if(p!=A.getrear())
           {

              if(p->data<10)cout<<"000";
              else if(p->data<100)cout<<"00";
              else if(p->data<1000)cout<<"0";
           }
           cout<<p->data<<',';

       }
template<class ElemType>
bool LinkQueue<ElemType>::QueueisEmpty() const
{
   if(front==rear)return true;
   return false;
}
template<class ElemType>
void Input_Int_Division( LinkQueue<ElemType> &A, string &str )
{
    int numlen=str.size(),i,number,len,bj=0;
    if(str[0]=='-')
        {
            bj++;
            A.change_front(-1);
            numlen--;
        }
    else A.change_front(1);
    if(numlen%4==0)len=numlen/4;
    else len=numlen/4+1;
    int num=numlen%4;
    for(int i = 1; i <= len; i ++)
        {
            if(4 * i <= numlen)
            {
                number = atoi(str.substr(numlen - 4*i+bj,4).c_str());
                A.enQueue(number);
            } else
            {
                number = atoi(str.substr(bj,num).c_str());
                A.enQueue(number);
            }
        }
    if(A.front_data()==-1)cout<<'-';
    auto p=A.getfront()->next;
    if(A.QueueLength()==1)
    {
        cout<<p->data;
    }
    else{
        if(p->next!=NULL)niprint (A,p->next);
    if(p->data<10)cout<<"000";
    else if(p->data<100)cout<<"00";
    else if(p->data<1000)cout<<"0";
    cout<<p->data;
    }
    cout<<endl;

}
/*template<class ElemType>
string Int_String( int result )
{

}*/
int compare(string &a,string &b,int i,int j,int len)
{
    for(int k=0;k<len;i++,j++,k++)
    {
        if(a[i]>b[j]){return 1;}
        if(a[i]<b[j]){return 2;}
    }
    return 0;
}
template<class ElemType>
int Two_LongNum_Compare(string &A_str,string &B_str)
{
    int alen=A_str.size(),blen=B_str.size(),signa=0,signb=0;
    if(A_str[0]=='-'){alen--;signa=1;}
    if(B_str[0]=='-'){blen--;signb=1;}
        if(alen>blen)return 1;
        else if(alen<blen)return 2;
        else return compare(A_str,B_str,signa,signb,alen);
}
string Int_String( int result )
{
    string str = "";
    string Result;
    stringstream ss;
    ss<<result;
    Result = ss.str();


    if(result == 0) str = "0000";
    else {
        if(result < 10 && result > 0) str = "000";
        if(result < 100 && result > 9) str = "00";
        if(result < 1000 && result > 99) str = "0";
        str.append(Result);
    }
    return str;
}
template<class ElemType>
void calculate(LinkQueue<ElemType>A,LinkQueue<ElemType>B,string &a,string &b)
{

    int f=Two_LongNum_Compare<int>(a,b);//要有<int>
    //绝对值大的放A中;
    if(f<=1)
    {
        Input_Int_Division(A,a);
        Input_Int_Division(B,b);
    }
    else
    {
        Input_Int_Division(B,a);
        Input_Int_Division(A,b);
    }
    int carry=0;//进位
    int Asignal=A.front_data(),Bsignal=B.front_data(),Atemp,Btemp,temp=0;
    string result2,result;

        while(!B.QueueisEmpty())
        {
            A.deQueue(Atemp);
            B.deQueue(Btemp);
            //中间的某一次计算
            temp = Atemp + Bsignal * Asignal *  Btemp + carry;

            if(temp > 9999)
            {
                carry = 1;
                temp = temp - 10000;
            }
            else if(temp < 0 )
            {
                carry = -1;
                temp =10000 + temp;
            }
            else
            {
                carry = 0;
            }

            //对中间某一次计算的拼接
            result2 = Int_String(temp);
            result2.append(",");
            result2.append(result);
            result = result2;
            result2 = "";


        }

        //如果A比较长,还没有遍历完
        while(!A.QueueisEmpty() || carry == 1)
        {
            Atemp = 0;
            A.deQueue(Atemp);
            temp = Atemp + carry;
            carry = 0;
            result2 = Int_String(temp);
            result2.append(",");
            result2.append(result);
            result = result2;
            result2 = "";
        }

        //最后在统一去除其中没有用的0
        int i = 0;
        for(;i < result.length();i ++)
        {
            if(result.at(i) == '0' || result.at(i) == ',')
            {
                continue;
            }else
            {
                break;
            }
        }
        string reTemp = result.substr(i,result.length());
        result = reTemp;

        //最高位上补上对应的符号位
        if(Asignal == -1)
        {
            result.insert(0,"-");
        }
        if(result.length()>0)
            result.erase(result.length() - 1);

        //输出最后的结果
        cout<<endl;
        if(result.length() == 0)
            cout<<"0";
        else
            cout<<result;

}

int main()
{
    string a,b;
    getline(cin,a);
    getline(cin,b);
    LinkQueue<int> A,B;
    calculate(A,B,a,b);
    return 0;
}

标签:结点,return,string,队列,int,result,str,front,数据结构
From: https://blog.csdn.net/2301_80102216/article/details/139562745

相关文章

  • 项目:基于httplib/消息队列负载均衡式在线OJ
    文章目录写在前面关于组件开源仓库和项目上线其他文档说明项目亮点使用技术和环境项目宏观结构模块实现compiler模块runner模块compile_run模块compile_server模块基于MVC结构的OJ服务什么是MVC?用户请求服务路由功能Model模块view模块Control模块写在前面关于组件......
  • Java数据结构与算法(最大子数组和动态规划)
    前言动态规划主要用于解决具有重叠子问题和最优子结构性质的问题。它通过将问题分解为子问题来解决复杂问题,每个子问题仅解决一次,并将其结果存储,以供后续使用,从而避免了重复计算。对应leetcode.-力扣(LeetCode)实现原理两次循环遍历,采用固定其实位置为i,不断滑动j的思想,来计......
  • Java数据结构与算法(爬楼梯动态规划)
    前言爬楼梯就是一个斐波那契数列问题,采用动态规划是最合适不过的。实现原理初始化:dp[0]=1;dp[1]=2;转移方程:dp[i]=dp[i-1]+d[i-2];边界条件:无具体代码实现classSolution{publicintclimbStairs(intn){if(n==1){return1;}......
  • 数据结构---树与二叉树
    个人介绍hellohello~,这里是code袁~......
  • 数据结构与算法之归并排序,以及它的代码实现与事例
    目录前言定义策略代码实现结果结束语前言今天是坚持写博客的第22天,我们来看看数据结构与算法当中的归并排序。定义首先我们来看看什么是归并排序?归并排序(MergeSort)是一种分治思想的排序算法。它将待排序的数组分成若干个子数组,每个子数组都是有序的,然后再将有序......
  • 数据结构学习笔记-堆排序
    堆排序算法的设计与分析问题描述:设计并分析堆排序【前置知识:什么是堆?】堆(Heap)是一种特殊的树形数据结构,它满足以下两个条件之一:最大堆(MaxHeap):每个节点的值都大于或等于其子节点的值。换句话说,根节点的值是整个堆中最大的。最小堆(MinHeap):每个节点的值都小于或等于其......
  • Python数据结构解析:从基本语法到实战应用,提升代码效率与性能
    基本语法Python提供了多种内置的数据结构,包括列表(List)、元组(Tuple)、集合(Set)、字典(Dictionary)等。这些数据结构具有不同的特点和用途,可以根据需求选择合适的数据结构。1.列表(List)列表是Python中最常用的数据结构之一,用于存储一系列元素,可以是不同类型的数据。列表使用......
  • 优先队列的实现:基于最小堆的 Java 实现
    优先队列是一种重要的数据结构,与普通队列不同,它每次从队列中取出的是具有最高优先级的元素。本文将介绍如何使用最小堆来实现优先队列,并提供详细的Java代码示例和解释。什么是优先队列?优先队列是一种抽象数据类型,其中每个元素都有一个与之相关的优先级。在删除操作中,总......
  • 另一个Java基于阻塞的定时消费内存队列(依赖guava)
    本文的代码是对一个Java基于阻塞的定时消费内存队列-Jackie_JK-博客园(cnblogs.com)方法的改进,完善了包装以及部分细节,非jdk21可能需要更换线程池类型。消费类型:@Getter@AllArgsConstructorpublicenumPushType{ELASTIC,SQL,;}队列参数枚举:@Getter@AllAr......
  • 数据结构(C语言严蔚敏版)——第二章 线性表
    前言:    对这一章节的学习,我深有体会,只有把链表这一重点弄清楚,才算开始真正的正式学习数据结构,刚开始学习链表的朋友可能会感到有点绕脑,但是当你掌握链表以后,你会发现其实原来学习编程还是很有意思的,慢慢在学习中找到成就感,不断收获。   当然,这章的重点还是在......