大非负整数加法运算

大数运算是一类算法应用,在密码学中比较常用。这里先完成一个最基本,最简单的大数运算-大非负整数加法运算。
大整数通常指计算结果超出int存储范围的,亦即会产生溢出的情况。比如32位无符号整数最大为:2^32-1=4294967295
所以接下来的算法就是要完成诸如4294967200 + 4294967220 = 8589934420这样的运算。
 
    解题步骤:
首先,从直观问题入手,为了保证能对任意位数整数进行运算,通常我们要给出两个整数字符串用以相加 str1 + str2,
然后,将str1 与 str2转换成整数数组int a[], b[],逐位进行加法运算,并保留结果与进位值。
         注:因为是加法运算,所以结果的位数最多是maxsize(a,b) + 1位
最后,输出结果。
 
    比如 362 + 1698 = 2060
    则:  num1[] = {2, 6, 3, 0, 0}   
            num2[] = {8, 9, 6, 1, 0}
    从最低位起进行计算:
        num1[0] + num2[0] = 2+8 = 10, 则num1[0] = 0, num1[1] = 6+1 = 7 
        num1[1] + num2[1] = 7+9 = 16, 则num1[1] = 6, num1[2] = 3+1 = 4
        num1[2] + num2[2] = 4+6 = 10, 则num1[2] = 0, num1[3] = 0+1 = 1
        num1[3] + num2[3] = 1+1 = 2,  则num1[3] = 2, num1[4] = 0+0 = 0
        num1[4] + num2[4] = 0+0 = 0,  则num1[4] = 0  
    现在结果存储在num1[]中{0, 6, 0, 2, 0}, 当然应该反向输出 2060
    
    伪码如下:
string    Add( string s1 , string s2)
{
    int num1 [] <- s1;
    int num2 [] <- s2;
    int len = max( s1 . length (), s2 . length()); 
    for i = 0 to len - 1
    {
        num1 [ i ] = num1 [ i ] + num2 [ i ];
        if ( num1 [ i ] >= 10)
        {
            num1 [ i ] -= 10; //将两位整数相加结果的个位保存在num1[i]中
            num1 [ i + 1 ] ++; //将两位整数相加结果的十位,即进位加到num1[i+1]中,以备下一步计算
        }
    }
    string res <- num1;
    return res;
}
     
    代码实现:
#include <string>
#include <iostream>
#include <cstddef>
#include <algorithm>

using std :: string;
using std :: cout;
using std :: cin;
using std :: max;
using std :: endl;

string Add( const string & s1 , const string & s2)
{
    //int num1[] <- s1;
    //int num2[] <- s2;

    int len = max( s1 . length (), s2 . length());
    int * num1 = new int [ len + 1 ];
    int * num2 = new int [ len + 1 ];
    for ( int i = 0; i <= len; ++ i)
    {
        num1 [ i ] = 0;
        num2 [ i ] = 0;
    }
   
    int len1 , len2;
    len1 = s1 . length();
    len2 = s2 . length();
    for ( int i = len1 - 1 , j = 0; i >= 0; -- i , ++ j)
    {
        num1 [ j ] = s1 [ i ] - '0';
    }
    for ( int i = len2 - 1 , j = 0; i >= 0; -- i , ++ j)
    {
        num2 [ j ] = s2 [ i ] - '0';
    }
    //add every int element in array
    for ( int i = 0; i < len; ++ i)
    {
        num1 [ i ] += num2 [ i ];
        if ( num1 [ i ] >= 10)
        {
            num1 [ i ] -= 10;
            num1 [ i + 1 ] ++;
        }
    }
    //store result.
    string ret;
    if ( len == 1)
    {
        ret . push_back( '0' + num1 [ 0 ]);
    }
    else
    {
        int i = len;
        while( num1 [ i ] == 0)
            -- i;
        for ( i; i >= 0; -- i)
        {
            ret . push_back( '0' + num1 [ i ]);
        }
    }
    delete [] num1;
    delete [] num2;
    return ret;
}
int main()
{
    string str1 , str2;
    cin >> str1 >> str2;
    string ret;
    ret = Add( str1 , str2);
    cout << ret << endl;

    return 0;
}
测试用例: 0+0, 1+0, 865799657896+972662725627
最后达到的效果应该是理论上可以对任何位大的整数进行计算,只要内存容量允许。
好的,以下是栈实现整数四则运算计算器的 C 代码: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define STACK_SIZE 100 // 定义栈的大小 // 定义栈结构体 typedef struct { int items[STACK_SIZE]; // 栈元素 int top; // 栈顶指针 } Stack; // 初始化栈 void initStack(Stack *s) { s->top = -1; } // 判断栈是否为空 int isEmpty(Stack *s) { return s->top == -1; } // 判断栈是否已满 int isFull(Stack *s) { return s->top == STACK_SIZE - 1; } // 入栈操作 void push(Stack *s, int num) { if (isFull(s)) { printf("栈已满,无法入栈。\n"); exit(1); } s->items[++(s->top)] = num; } // 出栈操作 int pop(Stack *s) { if (isEmpty(s)) { printf("栈为空,无法出栈。\n"); exit(1); } return s->items[(s->top)--]; } // 获取栈顶元素 int peek(Stack *s) { return s->items[s->top]; } // 计算表达式的值 int calculate(char *expr) { int i = 0, num = 0; Stack numStack, opStack; char c, op; initStack(&numStack); // 初始化数字栈 initStack(&opStack); // 初始化操作符栈 while (expr[i] != '\0') { c = expr[i]; if (isdigit(c)) { // 如果是数字 num = num * 10 + (c - '0'); if (!isdigit(expr[i+1])) { // 下一个字符不是数字,则表示数字已经结束 push(&numStack, num); // 将数字入栈 num = 0; // 将 num 置为零,用于下一个数字的计算 } } else if (c == '+' || c == '-') { // 如果是加或减 if (isEmpty(&opStack)) { // 操作符栈为空,直接入栈 push(&opStack, c); } else { while (!isEmpty(&opStack) && peek(&opStack) != '(') { // 将所有高优先级的操作符出栈 op = pop(&opStack); num = pop(&numStack); if (op == '+') { // 执行加法操作 push(&numStack, pop(&numStack) + num); } else { // 执行减法操作 push(&numStack, pop(&numStack) - num); } } push(&opStack, c); // 将当前操作符入栈 } } else if (c == '*' || c == '/') { // 如果是乘或除 if (isEmpty(&opStack) || peek(&opStack) == '+' || peek(&opStack) == '-') { // 操作符栈为空或栈顶为低优先级操作符,直接入栈 push(&opStack, c); } else { // 将所有高优先级的操作符出栈 while (!isEmpty(&opStack) && (peek(&opStack) == '*' || peek(&opStack) == '/')) { op = pop(&opStack); num = pop(&numStack); if (op == '*') { // 执行乘法操作 push(&numStack, pop(&numStack) * num); } else { // 执行除法操作 push(&numStack, pop(&numStack) / num); } } push(&opStack, c); // 将当前操作符入栈 } } else if (c == '(') { // 如果是左括号,直接入栈 push(&opStack, c); } else if (c == ')') { // 如果是右括号 while (!isEmpty(&opStack) && peek(&opStack) != '(') { // 将所有括号内的操作符出栈 op = pop(&opStack); num = pop(&numStack); if (op == '+') { // 执行加法操作 push(&numStack, pop(&numStack) + num); } else { // 执行减法操作 push(&numStack, pop(&numStack) - num); } } pop(&opStack); // 将左括号出栈 } i++; } // 将剩余的操作符出栈 while (!isEmpty(&opStack)) { op = pop(&opStack); num = pop(&numStack); if (op == '+') { // 执行加法操作 push(&numStack, pop(&numStack) + num); } else if (op == '-') { // 执行减法操作 push(&numStack, pop(&numStack) - num); } else if (op == '*') { // 执行乘法操作 push(&numStack, pop(&numStack) * num); } else if (op == '/') { // 执行除法操作 push(&numStack, pop(&numStack) / num); } } return pop(&numStack); // 返回最终的结果 } int main() { char expr[100]; printf("请输入表达式:\n"); scanf("%s", expr); printf("结果为:%d\n", calculate(expr)); return 0; } ``` 以上是栈实现整数四则运算计算器的 C 代码,使用方法为输入一个表达式并回车即可得到计算结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值