Tôi nghi ngờ việc truyền tới chuỗi và sau đó kiểm tra ký tự '0' là bước mất quá nhiều thời gian. Nếu bạn muốn tránh tất cả zero, có thể giúp tăng current
như sau:
(Edited - nhờ Aaron McSmooth)
current++;
for(int i = 10000000; i >= 10; i = i/10)
{
if (current % i) == 0
{
current = current + (i/10);
}
}
Đây là chưa được kiểm tra, nhưng khái niệm này phải rõ ràng: bất cứ khi nào bạn nhấn bội số của lũy thừa mười (ví dụ 300 hoặc 20000), bạn thêm công suất thấp hơn tiếp theo là 10 (trong ví dụ 10 + 1 và 1000 + 100 + 10 + 1 tương ứng) cho đến khi không còn số 0 trong số của bạn .
Thay đổi vòng kết nối while
tương ứng của bạn và xem điều này có giúp cải thiện hiệu suất cho vấn đề không.
Ồ, và bạn có thể muốn hạn chế đầu ra System.out
một chút. Mọi thứ mười, một hundreth hoặc 10000 lần là đủ?
Chỉnh sửa thứ hai: Sau khi ngủ, tôi nghi ngờ câu trả lời của tôi có thể hơi ngắn (đổ lỗi cho giờ muộn, nếu bạn muốn). Tôi chỉ đơn giản hy vọng rằng, một triệu lần lặp của current
sẽ đưa bạn đến giải pháp và để nó ở đó, thay vì tính toán các trường hợp chỉnh sửa bằng cách sử dụng log(current)
v.v.
Suy nghĩ thứ hai, tôi thấy hai vấn đề với toàn bộ vấn đề này. Một là số mục tiêu của bạn là 23.10345 là một leeeeettle để tròn cho thị hiếu của tôi. Sau khi tất cả, bạn đang thêm hàng ngàn mục như "1/17", "1/11111" và cứ thế, với các biểu diễn thập phân vô hạn và rất khó có thể thêm chúng vào chính xác 23.10345. Nếu một số chuyên gia cho toán học số nói như vậy, tốt - nhưng sau đó tôi muốn xem thuật toán mà họ đã đi đến kết luận này.
Sự cố khác liên quan đến vấn đề đầu tiên và liên quan đến giới hạn trong bộ nhớ số nhị phân trình bày các số hữu tỷ của bạn. Bạn có thể nhận được bằng cách sử dụng BigDecimals, nhưng tôi có những nghi ngờ của tôi.
Vì vậy, về cơ bản, tôi đề nghị bạn lập trình lại thuật toán số thay vì đi cho giải pháp bạo lực. Lấy làm tiếc.
Chỉnh sửa thứ ba: Vì tò mò, tôi đã viết điều này trong C++ để kiểm tra lý thuyết của mình. Nó chạy trong 6 phút và có khoảng 14,5 (khoảng 550 mio. Lần lặp). Chúng ta sẽ thấy.
Current version là
double total = 0;
long long current = 0, currPowerCeiling = 10, iteration = 0;
while(total < 23.01245)
{
current++;
iteration++;
if(current >= currPowerCeiling)
currPowerCeiling *= 10;
for(long long power = currPowerCeiling; power >= 10; power = power/10)
{
if((current % power) == 0)
{
current = current + (power/10);
}
}
total += (1.0/current);
if(! (iteration % 1000000))
std::cout << iteration/1000000 << " Mio iterations: " << current << "\t -> " << total << std::endl;
}
std::cout << current << "\t" << total << std::endl;
Tính currPowerCeiling
(hoặc tuy nhiên người ta có thể gọi đây) bằng tay tiết kiệm một số log10
và pow
tính toán mỗi lần lặp. Mỗi chút giúp - nhưng nó vẫn sẽ mãi mãi ...
Sửa thứ tư: Status là khoảng 66.000 mio lặp, tổng là lên đến 16,2583, thời gian chạy là vào khoảng 13 giờ. Không có vẻ tốt, Bobby S. - Tôi đề xuất một cách tiếp cận toán học hơn.
Làm thế nào là -19 một số nguyên dương? –
Đây có phải là bài tập về nhà không? –
@GregS Tôi xin lỗi nếu tôi không rõ ràng với ký hiệu của mình. 1, 2, 3, 4, 5, 6, 7, 8, 9, 11 TO 19 Dấu gạch ngang có nghĩa là một phạm vi từ số trước đến số cuối cùng. –