2010-07-28 1 views
5

Em trai 15 tuổi của tôi đang bắt đầu lập trình và anh ấy đã viết một chương trình nhỏ gọn giúp kết xuất tất cả các chữ cái và chữ số có sáu chữ số trở xuống. Mã của ông là một sextuple-lồng nhau cho vòng lặp mà cập nhật các yếu tố của một mảng sáu cấp độ. Nó trông xấu, nhưng chắc chắn là nhanh! Tôi chỉ cho anh ta cách làm một số đơn giản, và chuyển đổi những con số đó thành cơ sở 36.Làm cách nào để tính số cơ sở khác nhau trong C++?

Vấn đề lớn nhất là mã của tôi chậm hơn rất nhiều so với tôi, do sự phân chia mà tôi đang làm. Có cách nào mà tôi có thể chỉ đơn giản là giả định cơ sở 36 và sản lượng đếm từ 1 đến 36^6?

Lý tưởng nhất, tôi đang tìm cách để làm điều gì đó như

[base 36] 
for(int i = 0; i < 1000000; i++) 
    SaveForLaterFileOutput(i); 
+6

Bạn đang nhầm lẫn giá trị với bản trình bày. Tinh khiết đếm không phải là một khái niệm có thể được đưa ra một cơ số. Một phiên bản tái cấu trúc giải pháp anh trai của bạn có thể là tốt hơn của cả hai! –

+0

Không có tích hợp base36 xây dựng trong ngôn ngữ. Tuy nhiên, bạn không cần phân chia để làm những gì bạn muốn. – driis

Trả lời

3

Hãy thử điều này:

char buffer[1024]; 
for(int i = 0; i < 1000000; i++) 
     cout << itoa (i, buffer, 36); 

Ở đây nó là không có itoa (nếu bạn không có nó)

cout << setbase (36); 
for(int i = 0; i < 1000000; i++) 
     cout << i << endl; 
cout << setbase (10); // if you intend to keep using cout 

+2

'itoa' không nằm trong tiêu chuẩn và không phải tất cả thư viện C++ đều bao gồm nó. –

+0

Điều đó chắc chắn thực hiện điều này. Cảm ơn. – Jeffrey

+0

Cập nhật để có câu trả lời mà không có itoa (nhờ @Konrad Rudolph) –

1

để chuyển đổi một số căn 36: làm cho một ắc và bắt đầu từ một mức độ đủ cao, ví dụ 36^6. Nếu bộ cộng dồn cộng với số đó nhỏ hơn số của bạn, hãy thêm nó vào bộ tích lũy và lặp lại với cùng một mức độ (số đếm này là giá trị chữ số), nếu nó lớn hơn, vứt nó đi. Lặp lại cho độ thấp hơn cho đến khi bạn đạt đến 36^0. Theo dõi số lượng cho từng mức độ và đó là số của bạn ở cơ sở 36.

để in số đó theo cách có ý nghĩa, làm điều gì đó khác.

1

Tất cả số sử dụng trong tính toán tại cơ sở 2 Bất kỳ số nào khác bạn thấy chỉ là một ảo tưởng về cách nó được in. Do đó, SaveForLaterOutput của bạn là vô nghĩa.

Chức năng thư viện itoa() (chuyển thành "số nguyên thành ASCII") (những ngày này đã được thay thế bằng chức năng an toàn _itoa_s()) cho phép bạn chỉ định cơ sở khi chuẩn bị đầu ra.

+0

Không có thứ như "2" trong nhị phân, vì vậy về mặt kỹ thuật, tất cả các phép tính đều ở dạng nhị phân cơ sở 10 (không bị nhầm lẫn với số mười mà con người chúng ta thích quá nhiều). – fredoverflow

+0

Chỉ có 10 loại người trên thế giới: Những người hiểu nhị phân và những người không hiểu. –

+0

Có 10 loại người: những người hiểu ternary, những người không và những người nhầm lẫn nó cho nhị phân;) –

2

Có thể anh trai bạn cập nhật mảng 6 phần tử của mình mà không cần 6 vòng lồng nhau. Bằng cách thay đổi increment chức năng dưới đây, bạn có thể đếm trong bất kỳ "cơ sở" bạn chọn:

#include <algorithm> 
#include <iostream> 

#define NUM_CHARS 6 

// assuming ASCII 
// advances through a chosen sequence 0 .. 9, a .. z 
// or returns -1 on overflow 
char increment(char &c) { 
    if (c == 'z') return -1; 
    if (c == '9') { c = 'a'; return c; } 
    return ++c; 
} 

int main() { 
    char source[NUM_CHARS+1] = {0}; 
    std::fill_n(&source[0], NUM_CHARS, '0'); 
    while (true) { 
     std::cout << source << "\n"; 
     int idx = NUM_CHARS; 
     // increment and test for overflow 
     while (increment(source[--idx]) == -1) { 
      // overflow occurred: carry the 1 
      source[idx] = '0'; 
      if (idx == 0) return 0; 
     } 
    } 
} 

tôi đã không làm phiền với "hoặc ít hơn" một phần của vấn đề: tuy nhiên bạn đã thực hiện nó với 6 vòng có lẽ sẽ làm việc với kỹ thuật này. Nói đúng ra, đây là liệt kê các kết hợp, gần như nhưng không hoàn toàn giống như đếm.