I have the TaxiCab number program implemented in both Python and C++, I dont understand why same code gives different out put, can someone enlighten me on the workings of these loops.
Check the output of the codes, both language skipped certain pairs of answers.
#include <iostream>
#include <cmath>
#include <ctime>
#include "iomanip"
using namespace std;
int ramanujan(int n) {
int count = 0;
int i = 0;
int x;
int y;
std::cout << "Inside Ramanujan Function and out\n";
std::cout << setw(10) << "a" << setw(10) << "b" << setw(10) << "c" << setw(10)
<< "d" << setw(20) << "TaxiCab" << '\n';
std::cout << "\n"; // Needless to say you can ignore cout<<
for (i = 1; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int a = i + 2; a < n; a++) {
for (int b = a; b < n; b++) {
x = std::pow(i, 3) + std::pow(j, 3);
y = std::pow(a, 3) + std::pow(b, 3);
if (x == y && i != j && i != b && i != a && j != a && j != b &&
a != b) {
std::cout << setw(10) << i << setw(10) << j << setw(10) << a
<< setw(10) << b << setw(20) << x << '\n';
count = count + 1;
if (count > 15) {
return 0;
}
}
}
}
}
}
return 1;
}
int main() {
clock_t begin = clock();
ramanujan(50);
std::cout << "Done!\n";
clock_t end = clock();
double timeSec = (end - begin) / static_cast<double>(CLOCKS_PER_SEC);
std::cout << timeSec << " Seconds taken";
}
Python version
import time
from numba import njit
@njit # Comment this line if there is a Numba error
def ramanujan(n):
count = 0
print("a b c d TaxiCab")
for x in range(1, n):
for y in range(x, n):
for a in range(x, n):
for b in range(a, n): # Python for loops
z = (x ** 3) + (y ** 3)
z2 = (a ** 3) + (b ** 3)
if (
z == z2
and x != y
and x != a
and x != b
and y != a
and y != b
and a != b
):
print(x, y, a, b, z)
count = count + 1
if count > 15:
return # Breaks all for loops once 10 such pairs are found
# Dont worry about the problem setup
start = time.time()
ramanujan(50)
print("Done")
end = time.time()
print(end - start)
答案 0 :(得分:0)
由于浮点数的精度有限,使用std::pow
评估整数的幂容易产生舍入误差。
如果需要精确的值并且没有整数值范围溢出的风险,则更好的方法(可能更快)是使用简单的乘法。
如果我正确理解,以下是用于解决OP问题的稍微改进的(IMHO)算法。
#include <iostream>
#include <iomanip>
#include <vector>
#include <utility>
#include <map>
int ramanujan(int n)
{
using std::setw;
// Evaluate all the possible pairs and collect the sums
std::map<long, std::vector<std::pair<int, int>>> sums;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
auto sum = long(i) * i * i + long(j) * j * j;
auto it = sums.find(sum);
if ( it != sums.end() )
it->second.emplace_back(i, j);
else
sums.emplace(sum, std::vector<std::pair<int, int>>{{i, j}});
}
}
// Now print only the sums of powers (sorted) that
// are generated by more then one couple
int count = 0;
std::cout << setw(8) << "a" << setw(8) << "b"
<< setw(8) << "c" << setw(8) << "d" << setw(16) << "TaxiCab" << '\n'
<< "------------------------------------------------------\n";
for (auto const & i : sums)
{
if ( i.second.size() > 1 )
{
++count;
std::cout << setw(8) << i.second[0].first // a
<< setw(8) << i.second[0].second // b
<< setw(8) << i.second[1].first // c
<< setw(8) << i.second[1].second // d
<< setw(16) << i.first << '\n'; // a^3 + b^3 (= c^3 + d^3)
}
}
return count;
}
如果超过50,则将输出
a b c d TaxiCab ------------------------------------------------------ 1 12 9 10 1729 2 16 9 15 4104 2 24 18 20 13832 10 27 19 24 20683 4 32 18 30 32832 2 34 15 33 39312 9 34 16 33 40033 3 36 27 30 46683 17 39 26 36 64232 12 40 31 33 65728 4 48 36 40 110656 6 48 27 45 110808 Done!
答案 1 :(得分:0)
问题是由于std :: pow(x,n)函数引入的舍入错误。它返回一个浮点数并导致舍入错误。用long(i) i i代替pow(i,3)解决了这个问题。
任何人都可以评论为什么舍入错误对于Python来说不是问题吗?