Nếu bạn chỉ đang cố gắng đếm xem nó đã giảm bao nhiêu lần và không quan tâm đến đệ quy một cách cụ thể ... bạn có thể loại bỏ đệ quy. Mã dưới đây vẫn trung thành với Bài đăng gốc vì nó không được tính num <= 9
là cần giảm. Do đó, singleDigit(8)
sẽ có count = 0
, và singleDigit(39)
sẽ có count = 3
, giống như OP và câu trả lời được chấp nhận đang thể hiện:
const singleDigit = (num) => {
let count = 0, ret, x;
while (num > 9) {
ret = 1;
while (num > 9) {
x = num % 10;
num = (num - x) / 10;
ret *= x;
}
num *= ret;
count++;
console.log(num);
}
console.log("Answer = " + num + ", count = " + count);
return num;
}
Không cần thiết phải xử lý số 9 hoặc ít hơn (ví dụ. num <= 9
). Thật không may, mã OP sẽ xử lý num <= 9
ngay cả khi nó không được tính. Các mã ở trên sẽ không xử lý cũng không tính num <= 9
, tất cả. Nó chỉ vượt qua nó thông qua.
Tôi chọn không sử dụng .reduce
vì làm toán thực tế nhanh hơn nhiều để thực hiện. Và, đối với tôi, dễ hiểu hơn.
Suy nghĩ thêm về tốc độ
Tôi cảm thấy mã tốt cũng nhanh. Nếu bạn đang sử dụng loại giảm này (được sử dụng trong số học rất nhiều), bạn có thể cần phải sử dụng nó trên một lượng lớn dữ liệu. Trong trường hợp này, tốc độ sẽ trở thành tối quan trọng.
Sử dụng cả hai .map(Number)
và console.log
(ở mỗi bước giảm) đều rất dài để thực hiện và không cần thiết. Chỉ cần xóa .map(Number)
khỏi OP đã tăng tốc khoảng 4,38 lần. Việc xóa console.log
nó đã tăng tốc đến mức gần như không thể kiểm tra đúng cách (tôi không muốn chờ đợi nó).
Vì vậy, tương tự như câu trả lời của customcommander , không sử dụng .map(Number)
cũng không console.log
và đẩy kết quả vào một mảng và sử dụng .length
cho count
nhanh hơn nhiều. Thật không may cho câu trả lời của customcommander , sử dụng chức năng trình tạo thực sự rất chậm (câu trả lời đó chậm hơn khoảng 2,68 lần so với OP không có .map(Number)
và console.log
)
Ngoài ra, thay vì sử dụng .reduce
tôi chỉ sử dụng toán học thực tế. Chỉ riêng sự thay đổi này đã tăng tốc phiên bản chức năng của tôi lên gấp 3,5 lần.
Cuối cùng, đệ quy chậm hơn, nó chiếm không gian ngăn xếp, sử dụng nhiều bộ nhớ hơn và có giới hạn về số lần nó có thể "tái diễn". Hoặc, trong trường hợp này, có thể sử dụng bao nhiêu bước giảm để hoàn thành việc giảm toàn bộ. Đưa ra đệ quy của bạn cho các vòng lặp lặp giữ tất cả trên cùng một vị trí trên ngăn xếp và không có giới hạn lý thuyết về số lượng bước giảm có thể sử dụng để hoàn thành. Do đó, các hàm này ở đây có thể "giảm" hầu hết mọi số nguyên có kích thước, chỉ bị giới hạn bởi thời gian thực hiện và thời gian của một mảng có thể là bao lâu.
Tất cả điều này trong tâm trí ...
const singleDigit2 = (num) => {
let red, x, arr = [];
do {
red = 1;
while (num > 9) {
x = num % 10;
num = (num - x) / 10;
red *= x;
}
num *= red;
arr.push(num);
} while (num > 9);
return arr;
}
let ans = singleDigit2(39);
console.log("singleDigit2(39) = [" + ans + "], count = " + ans.length );
// Output: singleDigit2(39) = [27,14,4], count = 3
Chức năng trên chạy cực nhanh. Nó nhanh hơn khoảng 3,13 lần so với OP (không có .map(Number)
và console.log
) và nhanh hơn khoảng 8.4 lần so với câu trả lời của customcommander . Hãy nhớ rằng việc xóa console.log
khỏi OP sẽ ngăn không cho nó tạo ra một số ở mỗi bước giảm. Do đó, cần phải đẩy các kết quả này thành một mảng.
PT
.map(Number)
là dư thừa vì*
toán tử ép các giá trị thành số nào. ;-)