单链表ADT模板应用算法设计:长整数加法运算(有源码,不过老师也给过源码,感觉应该没人会看)(我想找一个一块码代码的人)

83 篇文章 5 订阅
67 篇文章 2 订阅

问题描述

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

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

(2)ADT的应用:使用该ADT设计并实现单链表应用场合的算法设计。

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

参考函数原型:

template<class ElemType>
void Long_Int_Add( LinkList<ElemType> &A, LinkList<ElemType> &B, string &result, const int &len_A, const int &len_B );

辅助函数原型:

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

template<class ElemType> 
void Input_Int_Division( LinkList<ElemType> &L, string &str, int &length );  (length:长整数分割后的block数,恰为存储用单链表的长度)

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

string Int_String( int result );

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

template<class ElemType>
int Two_LongNum_Compare( LinkList<ElemType> &A, LinkList<ElemType> &B, const int &len_A, const int &len_B );

(4)单链表ADT基本操作:单链表的逆置(实际计算时,鉴于单链表的顺序查找的特性,存储在单链表中的长整数需逆置,由原始的高位到低位排列,逆置为低位到高位降序排列。)

template<class ElemType>
void LinkList<ElemType>::ListReverse();
输入说明

第一行:长整数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

思路分析
  • 题目重点
    • 用单链表保存任意长度的长整数
    • 实现整数的加法运算
    • 题设附加:
      • 长整数低位拆分,数据域存放数据,4位一组
      • 链表头结点的数据域存放符号位
      • 可以调用两个长整数的绝对值比较大小
      • 根据单链表的连接顺序,建议逆序保存
        * 原数:高位->低位
        * 保存:低位->高位
尝试一
  • 题目倒是好理解,但是不是很理解所给的几个函数原型
关于参考函数原型
 template<class ElemType>
 void Long_Int_Add( LinkList<ElemType> &A, LinkList<ElemType> &B, string &result, const int &len_A, const int &len_B );

参数介绍:
 LinkList<ElemType> &A, LinkList<ElemType> &B:表示保存好的两个链表
 string &result:用来保存最终的结果
 const int &len_A, const int &len_B :两个的长整数的位数
关于辅助函数原型
  • 拆分函数
template<class ElemType> 
void Input_Int_Division( LinkList<ElemType> &L, string &str, int &length ); 

参数介绍 
length:长整数分割后的block数,恰为存储用单链表的长度
LinkList<ElemType> &L:最终用来存放分割之后的长整数的链表
string &str:外界用来传递的数组
  • 计算结果中间格式控制
string Int_String( int result );
result:是某一段的结点,将某一段进行加减运算之后的int型转成对应的字符串型
  • 个人认为大可不必,出现这个函数是因为最终的链表的结点的数据域确认是字符串型的,不是整型。其实使用整型也是可以的,只是处理确定的位数就比较费劲

  • 大可不必看我上面一段的论述,因为我上网搜了一下,发现从string转成int只要一句话,但是从int转成对应的string要好几句话,而且居然要额外的导入相关的包。具体的方法,看下面的额外知识补充

  • 绝对值比较大小

template<class ElemType>
int Two_LongNum_Compare( LinkList<ElemType> &A, LinkList<ElemType> &B, const int &len_A, const int &len_B );

参数介绍
LinkList<ElemType> &A, LinkList<ElemType> &B:两个存放长整数的链表
const int &len_A, const int &len_B:两个存放长整数链表的长度
  • 单链表的逆置
template<class ElemType>
void LinkList<ElemType>::ListReverse();
  • reverse在以前的题目中已经实现,在这里给出相关的连接reverse
基本的知识补充
  • string类型和int类型的相互转换函数
    • string转int
std::string str = "123";
int n = atoi(str.c_str());
  • int转string
#include<string>
#include<sstream>

using namespace std;
int main(){

	int n = 0;
	stringstream ss;
	string str;
	ss<<n;
	ss>>str;
}
  • string类型的切片函数
#include <string>
   string substr( size_type index, size_type num = npos );
   string s("What we have here is a failure to communicate");
   string sub = s.substr(21);
   cout << "The original string is " << s << endl;
   cout << "The substring is " << sub << endl;

输出

  The original string is What we have here is a failure to communicate
  The substring is a failure to communicate     

功能描述:
生成一个新的子串,子串的从index开始截取的,num个字符。若不写num,则默认是到字符串的末尾
注意,这函数是左闭右开的,起步是0,步长是4,是取包括0在内的四个字符,不包括第五个
在这里插入图片描述
同时不用担心,如果不够四个会怎么办。到了末尾会自动结束的
在这里插入图片描述

基本的框架构成
  • 将字符串进行四个一组的切片,然后生成对应的链表
  • 将对应的链表进行逆置(方便低位向高位进行进位或者是退位)
  • 先看两者的符号是否相同,相同就不要比较绝对值,不同就比较绝对值
  • 两者转成对应的int型进行运算,然后转成将结果转成对应的string生成相关的结果链表
源码——这个老师已经将源码放到了ppt,就肆无忌惮一次吧


/*
    description:convert int to string
*/
 string Int_String( int result )
 {
     stringstream ss;
     string resString;
     ss<<result;
     ss>>result;
     return resString;
 }

 /*
    description:compare the ABS of the two long int
    return     :X>Y return 1
               :X<Y return 2
               :X=Y return 0
 */

int Two_LongNum_Compare( LinkList<ElemType> &A, LinkList<ElemType> &B, const int &len_A, const int &len_B )
{
    LinkNode<ElemType> *temp1 = A.GetHead()->next;
    LinkNode<ElemType> *temp2 = B.GetHead()->next;
    int times = 0;

    //compare simple by the length of the stirng
    if(len_A < len_B)
    {
        return 2;
    }
    if(len_A > len_B)
    {
        return 1;
    }

    //on the condition that the length of them are equal
    while(times < len_A && times < len_B)
    {
        if(temp1->data < temp2->data)
        {
            return 2;
        }

        if(temp1->data > temp2->data)
        {
            return 1;
        }
        temp1 = temp1->next;
        temp2 = temp2->next;
        times ++;
    }

    //the value and the length of the linklist are the same
    return 0;
}

/*
    description:divide the whole string into pieces
*/

void Input_Int_Division( LinkList<ElemType> &L, string &str, int &length )
{
    int index = 0,step = 4,temp1;
    string substract = "";
    LinkNode<ElemType> *temp = L.getTail();
    int str_length= str.length();

    //tackle the singal of the number
    if(str.at(0) == '-')
    {
        L.GetHead()->data = -1;
        index = 1;
        str_length -= 1;
    }
    else
    {
        L.GetHead()->data = 1;
    }

    //tacle the situatio with different numbers of numbers
    if(str_length% 4 == 1)
    {
        substract = str.substr(index,1);
        temp1 = atoi(substract.c_str());
        temp->next = new LinkNode<ElemType>(temp1);
        temp = temp->next;
        index += 1;
        length ++;
    }

    if(str_length % 4 == 2)
    {
        substract = str.substr(index,2);
        temp1 = atoi(substract.c_str());
        temp->next = new LinkNode<ElemType>(temp1);
        temp = temp->next;
        index += 2;
        length ++;
    }

    if(str_length % 4 == 3)
    {
        substract = str.substr(index,3);
        temp1 = atoi(substract.c_str());
        temp->next = new LinkNode<ElemType>(temp1);
        temp = temp->next;
        index += 3;
        length ++;
    }

    //tackle other numbers
    while(index < str.length())
    {
        substract = str.substr(index,step);
        temp1 = atoi(substract.c_str());
        temp->next = new LinkNode<ElemType>(temp1);
        temp = temp->next;
        index += 4;
        length ++;
    }

}



void get_Sub(LinkList<ElemType> &res,LinkList<ElemType> &big
             ,LinkList<ElemType> &small)
{
    //create the revelent linklist to store the result
    LinkNode<ElemType> *temp = res.GetHead();

    //define two nodes to traverse two linkedlists
    LinkNode<ElemType> *temp1 = big.GetHead()->next;
    LinkNode<ElemType> *temp2 = small.GetHead()->next;

    //to store the temporary sum of two nodes
    int tempSub = 0;
    //to represents the carry from the low position
    int carry = 0;

    while(temp1 && temp2)
    {
        if((temp1->data + carry) < temp2->data)
        {
            tempSub = temp1->data - temp2->data + 10000;

            carry = -1;
        }
        else
        {
            tempSub = temp1->data - temp2->data + carry;
            carry = 0;
        }
        temp1 = temp1->next;
        temp2 = temp2->next;
        temp->next = new LinkNode<ElemType>(tempSub);
        temp = temp->next;

    }

    //deal with the surplus part of the numbers
    while(temp1) {
        //the situation that temp1 is not NULL
        temp->next = new LinkNode<ElemType>(temp1->data);
        temp1 = temp1->next;
        temp = temp->next;
    }

    res.ListReverse();
    temp = res.GetHead()->next;
    while(temp)
    {
        if(temp->data == 0)
        {
            res.GetHead()->next = temp->next;
        }
        temp = temp->next;
    }

}


void get_Sum(LinkList<ElemType> &res,LinkList<ElemType> &A
             ,LinkList<ElemType> &B)
{
    //define two nodes to traverse two linkedlists
    LinkNode<ElemType> *temp1 = A.GetHead()->next;
    LinkNode<ElemType> *temp2 = B.GetHead()->next;
    LinkNode<ElemType> *temp = res.GetHead();

    //to store the temporary sum of two nodes
    int tempSum = 0;
    //to represents the carry from the low position
    int carry = 0;
    //add up two numbers

    //determine the signal of the sum of two positive numbers
    if(A.GetHead()->data == -1)
    {
        res.GetHead()->data = -1;
    }
    else
    {
        res.GetHead()->data = 1;
    }

    //traverse two linklist to get the sum of the common parts
    while(temp1 && temp2)
    {
        tempSum = temp1->data + temp2->data + carry;
        if(tempSum >= 10000)
        {
            tempSum -= 10000;
            //substract the highest position of the number
            carry = 1;
        }
        else
        {
            carry = 0;
        }
        temp1 = temp1->next;
        temp2 = temp2->next;

        temp->next = new LinkNode<ElemType>(tempSum);
        temp = temp->next;

    }

    //deal with the surplus part of the numbers
    while(temp1)
    {
        //the situation that temp1 is not NULL
        temp->next = new LinkNode<ElemType>(temp1);
        temp1 = temp1->next;
        temp = temp->next;
    }


    while(temp2)
    {
        //the situation that temp1 is not NULL
        temp = new LinkNode<ElemType>(temp2);
        temp2 = temp2->next;
        temp = temp->next;
    }

    res.ListReverse();
    if(carry == 1)
    {
        temp = new LinkNode<ElemType>(1);
        temp->next = res.GetHead()->next;
        res.GetHead()->next = temp;
    }

}


void Long_Int_Add( LinkList<ElemType> &A, LinkList<ElemType> &B
                  , string &result, const int &len_A, const int &len_B )
{
    //create the revelent linklist to store the result
    LinkList<ElemType> resLinkList;
    LinkNode<ElemType> *temp = resLinkList.GetHead();

    //reverse two list to somplify the calculation
    A.ListReverse();
    B.ListReverse();

    //deal with the situation with the same signal
    if(A.GetHead()->data == B.GetHead()->data)
    {
       get_Sum(resLinkList,A,B);
    }
    else
    {
        int flag = Two_LongNum_Compare(A,B,len_A,len_B);
        if(flag == 0)
        {

            //A and B are opposite number
            temp->next = new LinkNode<ElemType>(0);
        }
        else if(flag == 1)
        {
            //A is bigger than B
            resLinkList.GetHead()->data = A.GetHead()->data;
            get_Sub(resLinkList,A,B);
        }
        else if(flag == 2)
        {
            //A is smaller than B
            resLinkList.GetHead()->data = B.GetHead()->data;
            get_Sub(resLinkList,B,A);
        }

    }



    A.ListReverse();
    B.ListReverse();



    temp = resLinkList.GetHead();
    string tempString = "";

    if(temp->data == -1)
    {
       tempString = "-";
       result.append(tempString);
    }

    while(temp)
    {
        tempString = Int_String(temp->data);
        result.append(tempString);
        temp = temp->next;
    }

    resLinkList.ListTraverse();
}


比较绝对值的大小
 /*
    description:compare the ABS of the two long int
    return     :X>Y return 1
               :X<Y return 2
               :X=Y return 0
 */
template<class ElemType>
int Two_LongNum_Compare( LinkList<ElemType> &A, LinkList<ElemType> &B, const int &len_A, const int &len_B )
{
    LinkNode<ElemType> *temp1 = A.GetHead()->next;
    LinkNode<ElemType> *temp2 = B.GetHead()->next;
    int times = 0;
    
    //compare simple by the length of the linklist
    if(len_A < len_B)
    {
        return 2;
    }
    if(len_A > len_B)
    {
        return 1;
    }
    
    //on the condition that the length of them are equal
    while(times < len_A && times < len_B)
    {
        if(atoi(temp1->data) < atoi(temp2->data))
        {
            return 2;
        }
        
        if(atoi(temp1->data) > atoi(temp2->data))
        {
            return 1;
        }
    }
    
    //the value and the length of the linklist are the same
    return 0;
}
将长字符串进行切片,并生成链表
/*
    description:divide the whole string into pieces
*/
void LinkList::Input_Int_Division( LinkLis &L, string &str, int &length )
{
    index = 0,step = 4;
    string substract = "";
    LinkNode *temp = L.getTail();
    
    while(index < length)
    {
        substract = str.substr(index,step);
        temp->next = new LinkNode(substract);
        temp = temp->next;
        index += 4;
    }
    
}
车祸现场
第一次提交

这个,错误的样例多的有一点发麻,我一时间有点不知所措,索性就自己去先试试几个通栏的样例
在这里插入图片描述

样例一:两个极大的正数 456,131,546,315,411 和165,489,646,161,206

在这里插入图片描述
由结果可知,是正确的
在这里插入图片描述

样例二、极小的两个数进行加减5+3=8
  • 错了,如下图
    在这里插入图片描述
  • 分析:很明显,连遍历输出都有问题,所以先看看遍历输出函数
  • 思路清理:
    • 如果链表存在,直接输出第一个结点
    • 是否输出“,”,则取决于是否存在下一个结点,如果存在就输出,不存在就不输出
修改之后得测试

在这里插入图片描述

  • 输出没有问题
第二次提交

在这里插入图片描述

  • 还是有问题,仍旧需要自拟样例进行猜测
样例二、一个正数一个负数,以不同的次序输入
  • 自拟测试样例,一个正数123456789,一个负数-235461,分别交换顺序进行输出。
  • 正数在上,负数在样例通过在这里插入图片描述
  • 正数在下,负数在上。通过测试
    在这里插入图片描述
样例三、极大的两个负数-123456789 和-123456789

在这里插入图片描述

  • 通过样例
样例四、两个极大的正数123456798 和123456789

在这里插入图片描述

  • 通过测试
不知道,只能花分数去买了

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

  • 没有通过样例
  • 原因:相等的代码段没有写完,忘记写迭代条件了
    在这里插入图片描述
  • 通过样例
第三次提交

在这里插入图片描述

  • 老师点了一下,还有一个地方没有认识到,那就是5000,和5000最终会生成新的结点,这都没有考虑到。同样的,还有一个退位没有考虑到,11000和-10000

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

  • 针对负数的零结点处理方法

在这里插入图片描述

  • 针对正数相加求和的进位

在这里插入图片描述

第三次提交

在这里插入图片描述

  • 我只看了一个样例,真的!过啦
样例假设方法的总结
  • 根据两个数字的大小进行比较,一大一小,一小一大,两者相等,三大类情况。(本热自己没有考虑到如何处理相等的情况)
分析与总结
  • 什么时候需要反转?

    • 比较绝对值大小是不需要的,因为一定要是从最高位开始比较的,逐渐向小的。链表长度不一致不用比较,直接出来
    • 当计算两个链表的和时候,是需要的,一因为涉及到处理进位和退位的信息传递
  • 关于补零:

    • 将长整数拆成若干固定长度的结点及逆行保存,已经破坏了原有的逻辑结构,所以要去弥补。主要有两个方面需要去弥补:
    • 中间结点的补零:一方面是作为一个独立的数字,另外一方面又是作为长正数的一部分。1 0001 0001 用链表表示:1,1,1
    • 最高位的进位:
      • 5000 + 5000 = 1 0000,新生成了一个结点,1,容易被忽略
      • 15000-10000 = 5000,消失了一个结点,就意味着要删除对应的结点
  • 注意还涉及到补位的问题,如果某一个段结果是小于四位数,那就要在对应的数字前面补零才能输出。最大值又不需要补零,

  • 关于字符串的切片,真的不想再吐槽什么了。如果一开始就四个字符四个字符的切片,最高位不足四位是不同补齐的,但是从最高位开始切,怎么判断会多几位,只能傻傻的用条件判定语句的。字符串又不好反转
    这道题写的我想吐

  • 我都不知道我脑子再抽什么,居然会这样想

temp = LInkList.GetHead();
temp = temp->next;
temp = new LinkNode();
//这完全就是鬼扯,怎么能连起来,你还费了那么多时间!
//temp指向的是一个空的地址,你只是改变了这个指针的值,并没有改变结点的逻辑结构
//temp=temp->next,此时的temp已经和head没有任何的关系了
//难道不应该这样吗
//没有看清,就在那里胡乱赋值,真的是
temp = LInkList.GetHead();
temp->next = new LinkNode();
  • 既然是将数字转成对应的单个节点,就意味着的某个结点的数字的范围,同时还有各个结点的补零问题
问题在于没有用好设计好的ADT,本来就是用ADT去实现你的算法,但是到了我这就是修改ADT,去适应我的算法!本末倒置
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
包含以下内容: 第一部分 基础篇 001 第一个C程序 002 运行多个源文件 003 求整数之积 004 比较实数大小 005 字符的输出 006 显示变量所占字节数 007 自增/自减运算 008 数列求和 009 乘法口诀表 010 猜数字游戏 011 模拟ATM(自动柜员机)界面 012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前n元素之和 021 求解钢材切割的最佳订单 022 通过指针比较整数大小 023 指向数组的指针 024 寻指定元素的指针 025 寻相同元素的指针 026 阿拉伯数字转换为罗马数字 027 字符替换 028 从键盘读入实数 029 字符行排版 030 字符排列 031 判断字符串是否回文 032 通讯录的输入输出 033 扑克牌的结构表示 034 用“结构”统计学生成绩 035 报数游戏 036 模拟社关系 037 统计文件的字符数 038 同时显示两个文件的内容 039 简单的文本编辑器 040 文件的字数统计程序 041 学生成绩管理程序 第二部分 数据结构篇 042 插入排序 043 希尔排序 044 冒泡排序 045 快速排序 046 选择排序 047 堆排序 048 归并排序 049 基数排序 050 二叉搜索树操作 051 二项式系数递归 052 背包问题 053 顺序表插入和删除 054 链表操作(1) 055 链表操作(2) 056 单链表就地逆置 057 运动分数统计 058 双链表 059 约瑟夫环 060 记录个人资料 061 二叉树遍利 062 浮点数转换为字符串 063 汉诺塔问题 064 哈夫曼编 065 图的深度优先遍利 066 图的广度优先遍利 067 求解最优交通路径 068 八皇后问题 069 骑士巡游 070 用栈设置密 071 魔王语言翻译 072 火车车厢重排 073 队列实例 074 K阶斐波那契序列 第三部分 数值计算与趣味数学篇 075 绘制余弦曲线和直线的迭加 076 计算高次方数的尾数 077 打鱼还是晒网 078 怎样存钱以获取最大利息 079 阿姆斯特朗数 080 亲密数 081 自守数 082 具有abcd=(ab+cd)2性质的数 083 验证歌德巴赫猜 084 素数幻方 085 百钱百鸡问题 086 爱因斯坦的数学题 087 三色球问题 088 马克思手稿中的数学题 089 配对新郎和新娘 090 约瑟夫问题 091 邮票组合 092 分糖果 093 波瓦松的分酒趣题 094 求π的近似值 095 奇数平方的有趣性质 096 角谷猜 097 四方定理 098 卡布列克常数 099 尼科彻斯定理 100 扑克牌自动发牌 101 常胜将军 102 搬山游戏 103 兔子产子(菲波那契数列) 104 数字移动 105 多项式乘法 106 产生随机数 107 堆栈四则运算 108 递归整数四则运算 109 复平面作图 110 绘制彩色抛物线 111 绘制正态分布曲线 112 求解非线性方程 113 实矩阵乘法运算 114 求解线性方程 115 n阶方阵求逆 116 复矩阵乘法 117 求定积分 118 求满足特异条件的数列 119 超整数的加法 第四部分 图形篇 120 绘制直线 121 绘制圆 122 绘制圆弧 123 绘制椭圆 124 设置背景色和前景色 125 设置线条类型 126 设置填充类型和填充颜色 127 图形文本的输出 128 金刚石图案 129 飘带图案 130 圆环图案 131 肾形图案 132 心脏形图案 133 渔网图案 134 沙丘图案 135 设置图形方式下的文本类型 136 绘制正多边形 137 正六边形螺旋图案 138 正方形螺旋拼块图案 139 图形法绘制圆 140 递归法绘制三角形图案 141 图形法绘制椭圆 142 抛物样条曲线 143 Mandelbrot分形图案 144 绘制布朗运动曲线 145 艺术清屏 146 矩形区域的颜色填充 147 VGA256色模式编程 148 绘制蓝天图案 149 屏幕检测程序 150 运动的小车动画 151 动态显示位图 152 利用图形页实现动画 153 图形时钟 154 音乐动画 第五部分 系统篇 155 读取DOS系统中的国家信息 156 修改环境变量 157 显示系统文件表 158 显示目录内容 159 读取磁盘文件 160 删除目录树 161 定义文本模式 162 设计立体窗口 163 彩色弹出菜单 164 读取CMOS信息 165 获取BIOS设备列表 166 锁住硬盘 167 备份/恢复硬盘分区表 168 设计口令程序 169 程序自我保护 第六部分 常见试题解答篇 170 水果拼盘 171 小孩吃梨 172 删除字符串中的特定字符 173 求解符号方程 174 计算标准差 175 求取符合特定要求的素数 176 统计符合特定条件的数 177 字符串倒置 178 部分排序 179 产品销售记录处理 180 特定要求的字符编 181 求解三角方程 182 新完全平方数 183 三重回文数 184 奇数方差 185 统计选票 186 同时整除 187 字符左右排序 188 符号算式求解 189 数字移位 190 统计最高成绩 191 比较字符串度 192 合并整数 193 矩阵逆置 194 删除指定的字符 195 括号匹配 196 字符串逆置 197 SIX/NINE问题 198 单词个数统计 199 方差运算 200 级数运算 201 输出素数 202 素数题 203 序列排序 204 整数各位数字排序 205 字符串字母移位 206 Fibonacc数列 第七部分 游戏篇 207 商人过河游戏 208 吃数游戏 209 解救人质游戏 210 打字训练游戏 211 双人竞走游戏 212 迷宫探险游戏 213 迷你撞球游戏 214 模拟扫雷游戏 215 推箱子游戏 216 五子棋游戏 第八部分 综合实例篇 217 综合CAD系统 218 功能强大的文本编辑器 219 图书管理系统 220 进销存管理系统

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值