需大量運算
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
static const auto Initialize = [] {
cin.sync_with_stdio(false); cin.tie(nullptr);
return nullptr;
}();
string Reverse(string number) {
string buffer = "";
for (int i = number.size() - 1; i >= 0; i--)
buffer += number[i];
return buffer;
}
string RemoveBack0(string number) {
for (int i = number.size() - 1; i >= 0; i--)
if (number[i] != '0')
return number.substr(0, i + 1);
return "";
}
string RemoveFront0(string number) {
for (int i = 0; i != number.size(); i++)
if (number[i] != '0')
return number.substr(i, number.size());
return "";
}
string RemoveDot(string number) {
string buffer = "";
for (int i = 0; i != number.size(); i++)
if (number[i] != '.')
buffer += number[i];
return buffer;
}
string RemoveSign(string number) {
for (int i = 0; i != number.size(); i++)
if (number[i] != '+' && number[i] != '-')
return number.substr(i, number.size());
return number;
}
int FindDot(string number) {
for (int i = 0; i != number.size(); i++)
if (number[i] == '.')
return i;
return number.size();
}
int Sign(string number) {
if (RemoveBack0(RemoveFront0(RemoveSign(RemoveDot(number)))) == "")
return 0;
int PositiveNegative = 1;
for (int i = 0; i != number.size(); i++)
if (number[i] != '+' && number[i] != '-')
return PositiveNegative;
else if (number[i] == '-')
PositiveNegative = -PositiveNegative;
return PositiveNegative;
}
bool IfInteger(string number) {
if (FindDot(number) == RemoveDot(number).size())
return true;
return false;
}
string Normalize(string number) {
int sign = Sign(number);
if (sign == 0)
return "0";
number = RemoveFront0(RemoveSign(number));
if (!IfInteger(number))
number = (IfInteger(RemoveBack0(number)) ? RemoveDot(RemoveBack0(number)) : RemoveBack0(number));
else if (number[number.size() - 1] == '.')
number = number.substr(0, number.size() - 1);
else if (number[0] == '.')
number = '0' + number;
return (sign == -1) ? '-' + number : number;
}
bool IfSmaller(string number1, string number2) {
int sign_1 = Sign(number1), sign_2 = Sign(number2);
if (sign_1 < sign_2)
return true;
if (sign_1 > sign_2)
return false;
number1 = RemoveSign(Normalize(number1)), number2 = RemoveSign(Normalize(number2));
int move_1 = 0, move_2 = 0;
if (!IfInteger(number1))
move_1 += (number1.size() - 1 - FindDot(number1));
if (!IfInteger(number2))
move_2 += (number2.size() - 1 - FindDot(number2));
number1 = RemoveDot(number1), number2 = RemoveDot(number2);
if (move_1 >= move_2)
for (int i = 1; i <= move_1 - move_2; i++)
number2 += '0';
else
for (int i = 1; i <= move_2 - move_1; i++)
number1 += '0';
if (number1.size() < number2.size())
return (sign_1 == -1) ? false : true;
if (number1.size() > number2.size())
return (sign_1 == -1) ? true : false;
for (int i = 0; i != number1.size(); i++)
if (number1[i] < number2[i])
return (sign_1 == -1) ? false : true;
else if (number1[i] > number2[i])
return (sign_1 == -1) ? true : false;
return false;
}
char Relation(string number1, string number2) {
if (IfSmaller(number2, number1))
return '>';
if (IfSmaller(number1, number2))
return '<';
return '=';
}
int CountZero(string number) {
if (Sign(number) == 0)
return 0;
int count = 0;
for (int i = number.size() - 1; i >= 0; i--)
if (number[i] != '0')
return count;
else
count++;
return count;
}
int Find_Number(string numbers[], string number, int left, int right) {
if (right - left <= 1) {
if (Relation(numbers[left], number) == '=')
return left;
return -1;
}
int middle = (left + right) / 2;
if (Relation(numbers[middle], number) == '=')
return middle;
if (Relation(numbers[middle], number) == '<')
return Find_Number(numbers, number, middle, right);
return Find_Number(numbers, number, left, middle);
}
void Big_Number_Sort(string numbers[], int count) {
if (count <= 1)
return;
for (int i = count - 1; i >= 1 && Relation(numbers[i], numbers[i - 1]) == '<'; i--)
swap(numbers[i], numbers[i - 1]);
}
string Multiplier(string number1, string number2) {
int sign_1 = Sign(number1), sign_2 = Sign(number2);
if (sign_1 * sign_2 == 0)
return "0";
number1 = Normalize(number1), number2 = Normalize(number2);
int zeros = CountZero(number1) + CountZero(number2), movedot = 0;
number1 = RemoveBack0(number1), number2 = RemoveBack0(number2);
if (!IfInteger(number1))
movedot += (number1.size() - 1 - FindDot(number1));
if (!IfInteger(number2))
movedot += (number2.size() - 1 - FindDot(number2));
number1 = Reverse(RemoveSign(RemoveDot(number1))), number2 = Reverse(RemoveSign(RemoveDot(number2)));
while (number1.size() > number2.size())
number2 += '0';
while (number1.size() < number2.size())
number1 += '0';
int carry = 0;
string result = "";
for (int i = 0; i != number1.size(); i++) {
for (int j = 0; j <= i; j++)
carry += int(number1[j] - '0') * int(number2[i - j] - '0');
result += char(carry % 10 + '0'), carry /= 10;
}
number1 = Reverse(number1), number2 = Reverse(number2);
for (int i = number1.size() - 2; i >= 0; i--) {
for (int j = 0; j <= i; j++)
carry += int(number1[j] - '0') * int(number2[i - j] - '0');
result += char(carry % 10 + '0'), carry /= 10;
}
while (carry)
result += char(carry % 10 + '0'), carry /= 10;
result = RemoveBack0(result);
if (zeros > movedot) {
result = Reverse(result);
zeros -= movedot;
for (int i = 1; i <= zeros; i++)
result += '0';
}
else {
movedot -= zeros;
if (movedot) {
while (movedot >= int(result.size()))
result += '0';
result = Reverse(result), result = result.substr(0, result.size() - movedot) + '.' + result.substr(result.size() - movedot, result.size());
}
else
result = Reverse(result);
}
if (sign_1 * sign_2 == -1)
result = '-' + result;
return result;
}
string Adder(string number1, string number2) {
if (Relation(number1, number2) == '<')
return Adder(number2, number1);
int sign_1 = Sign(number1), sign_2 = Sign(number2);
number1 = RemoveSign(Normalize(number1)), number2 = RemoveSign(Normalize(number2));
if (sign_1 == 0)
return number2;
if (sign_2 == 0)
return number1;
if (number1 == number2)
return ((sign_1 * sign_2 > 0) ? ((sign_1 > 0) ? Multiplier(number1, "2") : '-' + Multiplier(number1, "2")) : "0");
int move_dot_number1 = 0, move_dot_number2 = 0;
if (!IfInteger(number1))
move_dot_number1 += (number1.size() - 1 - FindDot(number1));
if (!IfInteger(number2))
move_dot_number2 += (number2.size() - 1 - FindDot(number2));
while (move_dot_number1 < move_dot_number2)
number1 += '0', move_dot_number1++;
while (move_dot_number1 > move_dot_number2)
number2 += '0', move_dot_number2++;
number1 = RemoveDot(number1), number2 = RemoveDot(number2);
if (sign_1 * sign_2 > 0) {
int carry = 0, buffer, i;
number1 = Reverse(number1), number2 = Reverse(number2);
for (i = 0; i != number2.size(); i++) {
buffer = int(number1[i] - '0') + int(number2[i] - '0') + carry;
number1[i] = char(buffer % 10 + '0'), carry = buffer / 10;
}
while (carry) {
if (i != number1.size()) {
buffer = int(number1[i] - '0') + carry;
number1[i] = char(buffer % 10 + '0'), carry = buffer / 10;
}
else
number1 += char(carry + '0'), carry = 0;
i++;
}
number1 = Reverse(number1);
if (move_dot_number1)
number1 = number1.substr(0, number1.size() - move_dot_number1) + '.' + number1.substr(number1.size() - move_dot_number1, number1.size());
return ((sign_1 > 0) ? Normalize(number1) : '-' + Normalize(number1));
}
else if (Relation(number1, number2) == '>') {
int i;
number1 = Reverse(number1), number2 = Reverse(number2);
for (i = 0; i != number2.size(); i++) {
number1[i] -= (number2[i] - '0');
if (number1[i] < '0')
number1[i] += 10, number1[i + 1]--;
}
for (; i != number1.size(); i++)
if (number1[i] < '0')
number1[i] += 10, number1[i + 1]--;
number1 = Normalize(Reverse(number1));
if (move_dot_number1)
number1 = number1.substr(0, number1.size() - move_dot_number1) + '.' + number1.substr(number1.size() - move_dot_number1, number1.size());
return Normalize(number1);
}
else {
number1 = '-' + Adder(number2, '-' + number1);
if (move_dot_number1)
number1 = number1.substr(0, number1.size() - move_dot_number1) + '.' + number1.substr(number1.size() - move_dot_number1, number1.size());
return Normalize(number1);
}
}
string Substractor(string number1, string number2) {
return Adder(number1, '-' + number2);
}
int main() {
string number;
while (cin >> number)
cout << Substractor(number, "1") << '\n';
}
出自https://hackmd.io/@Inversionpeter/r1XOHmvad