计算进位操作

时间:2015-08-29 18:21:37

标签: c

有人可以告诉我为什么我的程序会得到错误的答案吗?它必须计算总和中的进位操作数。我试过每一个测试包都出现在我的脑海里。我的输出没有错。

问题描述:

教导儿童一次从右到左添加多位数字。许多人发现“携带”操作 - 其中1从一个数字位置被携带到下一个位置 - 是一个重大挑战。你的工作是计算每组附加问题的携带操作次数,以便教育者可以评估他们的难度。

输入

每行输入包含两个小于10位的无符号整数。最后一行输入包含0 0。

输出

对于除最后一行之外的每一行输入,您应计算并打印由于添加这两个数字而产生的进位操作数,格式如下所示。

示例输入

123 456
555 555
123 594
0 0

示例输出

No carry operation.
3 carry operations.
1 carry operation.

这是我目前的代码:

#include<stdio.h>
int main()
{
    unsigned long long int a,b,m,n,rem_m,rem_n,judge=0,sum,count;
    while((scanf("%llu%llu",&m,&n))==2)
    {
        if(m==0 && n==0)
        {
            break;
        }
        count=0;
        while(m!=0 && n!=0)
        {
            rem_m=m%10;
            rem_n=n%10;
            if(judge==1)
            {
                rem_m++;
            }
            sum = rem_m+rem_n;
            judge=0;
            if(sum>=10)
            {
                count++;
                judge++;
            }
            m=m/10;
            n=n/10;
        }
        if(count==0)
        {
            printf("No carry operation.\n");
        }
        else
        {
            printf("%llu carry operations.\n",count);
        }
    }
    return 0;
}

5 个答案:

答案 0 :(得分:4)

  

以总和计算进位操作的数量

断言a,b是&gt; = 0:

Terse解决方案

为了好玩:)

int ds(int n){return n == 0 ? 0 : n%10 + ds(n/10);}
int numberOfCarryOperations(int a,int b){return (ds(a) + ds(b) - ds(a+b)) / 9;}

“ds”代表数字和。

可读

这是一个更易读的变体。

int digitSum(int n)
{
    int sum;
    for (sum=0; n > 0; sum+=n%10,n/=10);
    return sum;
}

int numberOfCarryOperations(int a,int b){
    // a, b >= 0
    return (digitSum(a) + digitSum(b) - digitSum(a+b)) / 9;
}

你可以用数学证明:每次进位时,digitSum减少9。

9,因为我们在数字系统10中,所以如果我们有携带,我们在一位数上“输掉10”,并且我们获得+1作为进位。

Pythonic版本

我不知道如何在C中执行此操作,但在python中,编写更好的digitSum函数很容易。在python中,我们可以轻松地从数字中创建数字列表,然后只需使用sum()来获取给定数字的digitSum。

这是一个简洁的python单线解决方案:

def numberOfCarryOperations(a, b):
    # f is the digitSum function
    f=lambda n:sum(map(int,str(n)));return(f(a)+f(b)-f(a+b))/9

答案 1 :(得分:1)

循环条件错误。你想要while(m!=0 || n!=0)(即,而其中至少有一个不是零)而不是while(m!=0 && n!=0),否则对999 9之类的问题的答案是错误的,它在一次迭代后会错误地停止并报告1个进位操作,而正确的答案应该是3.想象一下:你只想在它们两个为0时停止,所以循环必须继续只要至少有一个数字不是0。

此外,打印输出后忘记清除judge。您需要在再次读取输入之前清除它,或者您可能错误地使用以进位结束的先前计算中的judge == 1(此变量的名称选择对我来说似乎很奇怪,您应该将其重命名为更有意义的内容,例如carry,但这不是主要问题。)

ab未使用(您应该启用编译器警告)。

当计数为1时,样本输出显示单词 operation (如in,singular);你的程序总是写操作(复数)。如果您将此提交给自动判断,则代码将不会通过,因为输出与预期输出不完全匹配。要修复这个小细节,请将其替换为:

else
{
    printf("%llu carry operations.\n",count);
}

使用:

else
{
    printf("%llu carry operation%s.\n",count, count > 1 ? "s" : "");
}

这是固定版本:

#include <stdio.h>

int main(void)
{
    unsigned long long int m,n,rem_m,rem_n,judge=0,sum,count;
    while((scanf("%llu%llu",&m,&n))==2)
    {
        if(m==0 && n==0)
        {
            break;
        }
        count=0;

        /* We want || here, not && */
        while(m!=0 || n!=0)
        {
            rem_m=m%10;
            rem_n=n%10;
            if(judge==1)
            {
                rem_m++;
            }
            sum = rem_m+rem_n;
            judge=0;
            if(sum>=10)
            {
                count++;
                judge++;
            }
            m=m/10;
            n=n/10;
        }

        /* Clean up for next iteration */    
        judge = 0;

        if(count==0)
        {
            printf("No carry operation.\n");
        }
        else
        {
            printf("%llu carry operations.\n",count);
        }
    }
    return 0;
}

答案 2 :(得分:1)

红宝石解决方案是:

def count_carry_operations x, y
  return 0 if x == 0 && y == 0

  count = 0
  carry = 0

  while true
    return count if x == 0 && y == 0

    while x != 0 || y != 0
      xr = x % 10
      yr = y % 10

      xr += 1 if carry == 1

      sum = xr + yr
      carry = 0

      if sum >= 10
        count += 1
        carry += 1
      end

      x /= 10
      y /= 10
    end

    carry = 0
  end

  count
end

答案 3 :(得分:-1)

Java解决方案是:

public class Main {

    public  static int carry_count=0,carry_number=0;
    public static void main(String[] args) {
        System.out.println(Carry(99511,512));
    }
    private  static  int Carry(int num1,int num2){
       if(num1/10==0 || num2/10==0){
           int sum=num1%10+num2%10+carry_number;
           if(sum>=10){
               carry_number=1;
               carry_count++;
               return Carry(num1/10,num2/10);
           }else{
           return carry_count;}
       }else {
           int sum=num1%10+num2%10+carry_number;
           if(sum>=10){
               carry_number=1;
               carry_count++;
           }else {
               carry_number=0;
           }
           return Carry(num1/10,num2/10);
       }
    }
}

答案 4 :(得分:-1)

感兴趣的人的Java程序

static int numberOfCarryOperations(int num1, int num2) {
        int counter = 0;
        int result1 = 0;
        int result2 = 0;
        int carryNum = 0;
        while(  num1 != 0 || num2 != 0) {
            result1 = num1%10;
            result2 = num2%10;
            
            if(num1 > 0 ) {
                num1 = num1/10;
            }
            if( num2 > 0) {
                num2 = num2/10;
            }
            
            if( (result1 + result2+carryNum) > 9 ) {
                counter++;
                carryNum = 1;
            } else {
                carryNum = 0;
            }
        }
        return counter;
    }
    
    
    public static void main(String[] args) {
        System.out.println(numberOfCarryOperations(123, 456)); // 0
        System.out.println(numberOfCarryOperations(555, 555)); // 3
        System.out.println(numberOfCarryOperations(900, 11)); // 0
        System.out.println(numberOfCarryOperations(145, 55)); // 2
        System.out.println(numberOfCarryOperations(0, 0));// 0
        System.out.println(numberOfCarryOperations(1, 99999) );// 5
        System.out.println(numberOfCarryOperations(999045, 1055) );// 5
        System.out.println(numberOfCarryOperations(101, 809)); // 1
        System.out.println(numberOfCarryOperations(189, 209) );// 1
    }