今天看剑指OFFER,看到一个相关题目,要求定义一个函数,在该函数中可以实现任意两个整数的加法。由于没有限定输入两个数的大小范围,所以必须当作大数来处理。之前做面试题17 ,要求从1打印到最大的N位数,其中有一种思路和这题有点类似,花了一个小时,才编写出来,在输入格式正确的情况下(只输入数字,两个数字之间用空格隔开),能通过自己的所有案例,贴上代码,纪念自己复习算法的最后这段时光。共190+行代码,感觉可以优化一下,但是如果只是简单的AC,应该够了。
/// <summary>
/// 作者:陈鸿
/// 编辑时间:2018年6月9日 23:09:50
/// 问题描述:
/// 定义一个函数,在该函数中可以实现任意两个整数的加法
/// 注意点:
/// 1、没有限定输入的数的范围,必须当作大数来处理
/// 2、需要考虑三种加法:正数+正数、负数+负数、正数+负数
/// </summary>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 任意两个数的加法
{
class Program
{
static void Main(string[] args)
{
while (true)
{
string strInput = Console.ReadLine();
string num1 = strInput.Split(' ')[0];
string num2 = strInput.Split(' ')[1];
Solution s = new Solution();
s.AddNumber(num1, num2);
}
}
}
class Solution
{
public void AddNumber(string num1, string num2)
{
if (num1 == null || num2 == null)
return;
//sumIsNagetive用来储存结果的符号
bool sumIsNagetive = false;
//num1IsNagetive、num2IsNagetive用来保存相加的两个数的符号
bool num1IsNagetive = false, num2IsNagetive = false;
//为两个数去掉符号
if (num1[0] == '-')
{
num1IsNagetive = true;
num1 = num1.Remove(0, 1);
}
if (num2[0] == '-')
{
num2IsNagetive = true;
num2 = num2.Remove(0, 1);
}
//令sum1成为大数
if (!CheckMaxNumber(num1, num2))
{
string sum = num1;
num1 = num2;
num2 = sum;
bool temp = num1IsNagetive;
num1IsNagetive = num2IsNagetive;
num2IsNagetive = temp;
}
//判断和是否为负数
//1、都为负数
//2、一正一负,负数大于正数
if (CheckResultIsNagetive(num1, num2, num1IsNagetive, num2IsNagetive))
{
sumIsNagetive = true;
}
//如果都是正数或者负数,则相加,如果一个是正数一个是负数就相减
if ((num1IsNagetive && num2IsNagetive) || (!num1IsNagetive && !num2IsNagetive))
{
int takeOver = 0; //进位
int num1Length = num1.Length - 1; //获得num1的位数
int num2Length = num2.Length - 1; //获得num2的位数
for (int i = num1.Length - 1; i >= 0; i--, num1Length--, num2Length--)
{
int nsum = (int)(num1[num1Length] - '0') + takeOver;
if (num2Length >= 0)
nsum += (int)(num2[num2Length] - '0');
if (nsum >= 10)
{
takeOver = 1;
nsum -= 10;
char[] ch = num1.ToCharArray();
ch[i] = (char)(nsum + '0');
num1 = new string(ch);
}
else
{
char[] ch = num1.ToCharArray();
ch[i] = (char)(nsum + '0');
num1 = new string(ch);
takeOver = 0;
}
}
if (takeOver == 1)
{
num1 = num1.Insert(0, "1");
}
}
else if ((!num1IsNagetive && num2IsNagetive) || (num1IsNagetive && !num2IsNagetive))
{
int takeBack = 0; //退位
int num1Length = num1.Length - 1; //num1的位数
int num2Length = num2.Length - 1; //num2的位数
for (int i = num1Length; i >= 0; i--, num1Length--, num2Length--)
{
int subtractNum = (int)(num1[num1Length]-'0') - takeBack;
if (num2Length >= 0)
subtractNum -= (int)(num2[num2Length]-'0');
if (subtractNum < 0)
{
takeBack = 1;
subtractNum += 10;
char[] ch = num1.ToCharArray();
ch[i] = (char)(subtractNum + '0');
num1 = new string(ch);
}
else
{
char[] ch = num1.ToCharArray();
ch[i] = (char)(subtractNum + '0');
num1 = new string(ch);
}
}
}
if (sumIsNagetive)
num1 = num1.Insert(0, "-");
PrintNum(num1);
}
/// <summary>
/// 检查两个数相加的结果是正数还是负数
/// </summary>
/// <param name="num1">较大的加数</param>
/// <param name="num2">较小的加数</param>
/// <param name="num1IsNagetive">较大的加数的符号,true为负数</param>
/// <param name="num2IsNagetive">较小的加数的符号,true为负数</param>
/// <returns>返回值为真说明相加的结果是一个负数</returns>
private bool CheckResultIsNagetive(string num1, string num2, bool num1IsNagetive, bool num2IsNagetive)
{
bool isNagetive = false;
if (num1IsNagetive && num2IsNagetive)
isNagetive = true;
if (num1IsNagetive && !num2IsNagetive)
if (CheckMaxNumber(num1, num2))
isNagetive = true;
return isNagetive;
}
/// <summary>检查第一个参数和第二个参数的大小,如果第一个参数大于第二个参数,返回真,否则返回假</summary>
private bool CheckMaxNumber(string num1, string num2)
{
if (num1.Length > num2.Length)
return true;
if (num1.Length == num2.Length)
{
for (int i = 0; i < num1.Length; i++)
if (num1[i] > num2[i])
return true;
}
return false;
}
private void PrintNum(string str)
{
bool isBeginning0 = true;
//由于有可能会出现结果为0这种情况,所以必须判断一下,如果是0,则输出一个0
if (str[0] == '0' && str.Length == 1)
{
Console.WriteLine("0");
return;
}
for (int i = 0; i < str.Length; i++)
{
if (isBeginning0 && str[i] != '0')
{
isBeginning0 = false;
}
if (!isBeginning0)
Console.Write(str[i]);
}
Console.WriteLine();
}
}
}