两数相乘算法,输入的数字为string类型
2013-09-23 11:46
267 查看
这是一道腾讯的笔试题,原题有小数点要求。这里只分析下int型的。网上找到一种解法,看过之后表示解法不错,自己敲了一遍并做一些注释。代码在网上随意可以找到,如下:
代码中用一个链表存储计算出的每个位的数。其中head头为个位(当然这里没有考虑float类型),依次next指向十位,百位...。可以看到定义了很多指针,有*p,*p1,*Linehead。p的作用是用来申请操作位,当计算出下一位后,如果不存在p,这回 new 一个 Node。p1的作用是保存当前的操作位,p1是从head开始,一直遍历到运算结束,每一次循环p1的值都在改变。Linehead是调整p1的起始位置,例如乘数是一个两位数,那么个位数乘以被乘数时的起始位置是个位,即head;当十位数乘以被乘数时的起始位置是十位,即head->next。此时的p1
= Linehead = Linehead ->next。
这里可以画一张图:
1 1
X 1 1
1 1 <-p1 = Linehead = head (遍历结束之后,Linehead = Linehead->next)
1 1 <-p1=Linehead
1 2 1
现在来看下怎么计算p1的。
temp1 = p1->data + (*ap-48)*bbit + temp;
p1->data = temp1 % 10;
其中temp1为当前计算为的乘积,temp为进位的数。
第一轮:temp=0 p1->data =0 head->data =1 (head->next)->data = 1 Linehead = Linehead->next
第二轮:temp=0 p1 = Linehead = (head->next) p1->data=1 temp1=2 即(head->next)->data=2 (head->next->next)->data = 1
最终得到 head->..... = 1 2 1
#include <iostream> using namespace std; #define MAX 10000 //链表结点 struct Node{ int data; Node *next; }; //递归输出,其实是链表的逆向输出,因为保存时是 //从个位->十位->...所以输出要逆向 void output(Node *head) { if(!head->next&&!head->data) return; output(head->next); cout<<head->data; } void Mul(char *a,char *b) { char *ap = a, *bp = b; Node *head = new Node; head->data = 0; head->next = 0; //乘数从低位到高位每一位与被乘数的积起始位置逐一++ Node *Linehead = head; Node *p,*p1; //temp为相乘的进位,temp1为当前计算的乘数,bbit保存char转化的int数字 int temp = 0,temp1,bbit; while(*bp) //若乘数不为空 { p = Linehead->next; p1 = Linehead; bbit = *bp-48; while(*ap||temp) //若被乘数不为空或者有进位 { if(!p) { p = new Node; p->data = 0; p->next = 0; p1->next = p; } if(*ap==0) temp1 = temp; else { temp1 = p1->data + (*ap-48)*bbit + temp; ap++; //被乘数下一位 } p1->data = temp1 % 10; //保留当前位 temp = temp1 / 10; //得到进位的下一位 p1 = p; p = p->next; } ap = a; bp++; Linehead = Linehead->next; //乘数下一位 } p = head; output(p); cout<<endl; while(head) { p = head->next; delete head; head = p; } } void main() { cout<<"请输入两个数"<<endl; char test1[MAX],test2[MAX]; cin.getline(test1,MAX,'\n'); cin.getline(test2,MAX,'\n'); //strrev为字符串的倒位 Mul(strrev(test1),strrev(test2)); system("PAUSE"); }
代码中用一个链表存储计算出的每个位的数。其中head头为个位(当然这里没有考虑float类型),依次next指向十位,百位...。可以看到定义了很多指针,有*p,*p1,*Linehead。p的作用是用来申请操作位,当计算出下一位后,如果不存在p,这回 new 一个 Node。p1的作用是保存当前的操作位,p1是从head开始,一直遍历到运算结束,每一次循环p1的值都在改变。Linehead是调整p1的起始位置,例如乘数是一个两位数,那么个位数乘以被乘数时的起始位置是个位,即head;当十位数乘以被乘数时的起始位置是十位,即head->next。此时的p1
= Linehead = Linehead ->next。
这里可以画一张图:
1 1
X 1 1
1 1 <-p1 = Linehead = head (遍历结束之后,Linehead = Linehead->next)
1 1 <-p1=Linehead
1 2 1
现在来看下怎么计算p1的。
temp1 = p1->data + (*ap-48)*bbit + temp;
p1->data = temp1 % 10;
其中temp1为当前计算为的乘积,temp为进位的数。
第一轮:temp=0 p1->data =0 head->data =1 (head->next)->data = 1 Linehead = Linehead->next
第二轮:temp=0 p1 = Linehead = (head->next) p1->data=1 temp1=2 即(head->next)->data=2 (head->next->next)->data = 1
最终得到 head->..... = 1 2 1
相关文章推荐
- String类型的超大的数字转2进制输出(算法面试)
- String数组的输入转换成int类型后再进行排列之算法1
- 输入内容(string类型的),统计字母/数字/空格的数量 [C#]
- 34-输入5个数字,使用递归的算法倒叙输出
- 键盘操作(限制输入类型,数字,英文)
- 【算法】输入一个已经按升序排过的数组和数字,在数组中查找两个数字,使得它们的和正好是输入那个数字。
- String类型数字始终保留两位小数
- java类型转换:String类型的数字转换成固定格式类型输出的String(有无规则均可)
- 输入两数相乘-经典递归
- string类型转换为数字a
- C#判断一个String是否为数字类型
- string 类型的输入操作符和geline 函数对空白字符(空格,换行,制表)的处理
- [置顶] EditText设置输入的类型,只能输入纯数字,只能输入手机号码,只能输入邮箱等等。
- 在开发过程中,数据的输入和输出全部用string类型进行交互,是否会更好一些?
- 通过输入卡号前10位数字判断是哪个银行的卡和类型(储蓄卡or信用卡)
- 2012-06-13 16:50 Android限定EditText的输入类型为数字或者英文
- Java String与其他类型之间的转化及其算法练习
- EditText设置输入的类型,比如说限制只能输入字母和数字
- 控制C#中的文本输入只能是数字类型
- mongodb 将数字类型转换成String