Algorithm->string类实现大数运算

请听题:
在这里插入图片描述

乍一看题目,这也太简单了吧,组成一个三角形的条件不就是任意两条边长度之和大于第三边嘛,一开始我也是这样想的,一分钟写完,提交运行,结果当然是:您的代码通过了00.00%的测试用例。这里需要注意题目给的数据范围:1 <= a,b,c <= 10^100,int型能储存的数据范围是-2147483648 ~ 2147483647,大概就是21亿,109 是一亿,1011 就是100亿,已经远远超出了int的范围,所以这时候就可以考虑用string接收了。

double类型的变量可表示的范围是-21024 ~ 21024 ,也可以用于此题

这题的关键就是用string类实现大数的加法运算,这里提供一种思路:
在这里插入图片描述
如图,要用string类计算加法,有两种方法可选,一种按照原来的顺序,一种是逆序之后再进行预算。显然,逆序之后从前往后运算的顺序和平时我们计算加法的顺序是相似的,只需要在运算结束后将字符串再逆序一下就可以了。步骤如下:

  1. 将两个字符串逆序,较短的后面补充合适个数的‘0’
  2. 运算(运算时要讲字符转换成数字才能计算),详细过程在后面讲
  3. 将得到的结果逆序后输出

程序:

string add(string& s1, string& s2) {
	reverse(s1.begin(), s1.end());
	reverse(s2.begin(), s2.end());
	//进位位
	int carry = 0;
	//暂存每两位的和
	int tmp = 0;
	size_t i = 0;
	//存放和的字符串
	string sum;
	//在短的末尾补0
	if (s2.size() > s1.size()) {
		swap(s1, s2);
		s2.resize(s1.size(), '0');
	}
	else {
		s2.resize(s1.size(), '0');
	}
	//sum的大小和较长的字符串一样
	sum.resize(s1.size());
	for (; i < s1.size(); i++) {
		tmp = (s1[i] - '0') + (s2[i] - '0') + carry;
		if (tmp >= 10) {
			carry = tmp / 10;
		}
		else
			carry = 0;
		sum[i] = tmp % 10 + '0';
	}
	//处理最高位
	if (sum[i] - '0' >= 10) {
		sum[i + 1] = (sum[i] - '0') / 10 + '0';
		sum[i] = (sum[i] - '0') % 10 + '0';
	}
	reverse(sum.begin(), sum.end());
	return sum;
}

有了这个方法后,判断三个数字能否构成三角形就轻而易举了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include<iostream> #include<vector> #include<algorithm> #include<string> using namespace std; struct Node { Node(double d, Node* l = NULL, Node* r = NULL, Node* f = NULL) :data(d), left(l), right(r), father(f) {} double data; Node* father, * left, * right; //父,左右孩子 string code; //存储编码 }; typedef Node* Tree; //通过中序,构建编码 void creatCode(Node* node, string s) { if (node != NULL) { creatCode(node->left, s + '0'); if (node->left == NULL && node->right == NULL) //是叶子节点就更新编码 node->code = s; creatCode(node->right, s + '1'); } } int main() { vector<double> w; vector<Node*> node; double tmp; Tree tree; cout << "输入权值,数字后紧跟回车结束:"; do { cin >> tmp; w.push_back(tmp); } while (getchar() != '\n'); sort(w.begin(), w.end(), greater<double>()); //降序排序 for (int i = 0; i < w.size(); i++) node.push_back(new Node(w[i])); vector<Node*> out = node; Node* left, * right; do { right = node.back(); node.pop_back(); //取出最小的两个 left = node.back(); node.pop_back(); node.push_back(new Node(left->data + right->data, left, right)); //将新结点(求和)推进数组中 left->father = node.back(); //更新父结点 right->father = node.back(); out.push_back(node.back()); //存储此结点 for (int i = node.size() - 1; i > 0 && node[i]->data > node[i - 1]->data; i--) //从末尾冒泡,排序 swap(node[i], node[i - 1]); } while (node.size() != 1); //构建树结构 tree = node.front(); //剩余的一个结点即根结点 creatCode(tree, ""); printf("结点\t父结点\t左孩子\t右孩子\t编码\n"); for (int i = 0; i < out.size(); i++) printf("%.2lf\t%.2lf\t%.2lf\t%.2lf\t%s\n", out[i]->data, out[i]->father == NULL ? 0 : out[i]->father->data, out[i]->left == NULL ? 0 : out[i]->left->data, out[i]->right == NULL ? 0 : out[i]->right->data, out[i]->code.c_str()); return 0; }根据代码写流程图
最新发布
06-12

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值