2013-11-10 3 views
2

Итак, я написал это небольшое приложение, которое преобразует десятичное число в восьмеричное, и выводит правильный ответ только в обратном порядке. Например, если ответ на преобразование был равен 17, приложение отобразило бы его как 71. Любая помощь была бы высоко оценена.C++ Изменение десятичного числа до восьмеричного, выход назад

; 
    int _tmain(int argc, _TCHAR* argv[]) 
{ 
int octal, total = 0; 
    cout<< "please enter a decimal: "; 
    cin >> octal; 
    while(octal > 0) 
    { 
       total = octal % 8; 
     octal /= 8; 
     cout << total; 
    } 
    cout << endl; 
     _getche(); 
     return 0; 
} 
+2

Вы знакомы с массивами (Возможное решение №1) или рекурсивными функциями (Возможное решение № 2)? Довольно плохим решением было бы сохранить вывод в строке и отменить это («плохо», потому что есть лучшие способы). – usr2564301

+1

Почему строки хуже, чем массивы? Это почти то же самое – Machtl

+0

@Machtl: * почти * то же самое. С помощью строки вы можете использовать библиотечную функцию 'strrev' или написать свой собственный. Используя массив, вы не используете библиотечную функцию, вы программируете «ближе к металлу». Вы даже не должны * физически * отменить массив. Поскольку это кажется упражнением, а не производственным кодом, я бы не пошел на библиотечную функцию - то же самое относится к «printf, используя'% o' ». – usr2564301

ответ

1

Вам нужно взять сумму, а затем распечатать конечный результат, что-то вроде

int n=0; 
while (octal > 0) { 
    total += (pow(10,n++))*(octal % 8); 
    octal /= 8; 
} 
cout << total << endl; 

Просто печатая цифру будет печатать их в обратном порядке, так как вы печатаете мельчайшие биты первыми.

Как было отмечено в комментариях, механизм выше будет работать только для преобразования баз меньше 10.

+2

Вы не забыли «восьмеричные/= 8»? В противном случае цикл никогда не остановится – Machtl

+0

Хорошее решение, но это * преобразует * ввод в десятичную нотацию. Тот же алгоритм не будет работать в шестнадцатеричном формате. – usr2564301

+0

Набрав быстрее, чем мой ментальный писатель кода мог бы последовать ... Спасибо за головы – abiessu

4

Вы можете использовать станд :: Октябрь номер печати в восьмеричной системе счисления.

int n = 123; 
std::cout << std::oct << n << std::endl; 

Аналогично вы можете напечатать число в различных нотаций, как десятичное - std::dec и шестнадцатеричной - std::hex.

Эти манипуляторы ввода/вывода позволяют пользователю анализировать строки в различных обозначениях.

int n; 
std::istringstream("24") >> std::hex >> n; 
std::cout << n << std::endl; // n is 36 (decimal) 
1

У вас все в порядке, но вы должны распечатать остатки в обратном порядке, чтобы получить правильный ответ. Напр. если ans равно 17, то десятичный эквивалент будет 1 * 8^1 + 7 * 8^0. единичная цифра будет остатком, полученным делением числа на 8, следующая цифра влево будет остатком, полученным делением числа на 8^2 и так далее. Поэтому, если число в восьмеричной цифре составляет n цифр, то самым значимым разрядом будет остаток, полученный путем деления числа на 8^n. Вот почему вы должны распечатать остаток в обратном порядке.

1

Раствор с использованием массива для временного хранения:

int octal, total = 0, length=0; 
char storage[12]; /* 11 octal digits add up to > 1 billion */ 
octal = 123; 
while (octal > 0) 
{ 
    storage[length] = octal % 8; 
    octal /= 8; 
    length++; 
} 
while (--length >= 0) 
    printf ("%d", storage[length]); 
printf ("\n"); 

(я оказался в режиме C, следовательно, printf ы Изменение к cout, где это необходимо..)

Наиболее важным моментом является что вы связаны размером storage. Вы можете установить его на разумный размер - самый большой положительный восьмеричный размер, который вы можете поместить в целое число: 017777777777 -, и даже необоснованный размер допустим (вы можете установить его на 20, что будет только отбрасывать 8 дополнительные байты, в эти дни это ничего). Размер хранилища определяется тем, насколько велика цифра вашего номера в восьмеричном, для наибольшего числа, которое вы можете ввести.

Предположим, что измените и 8 с на 2; то вы можете использовать эту же процедуру для двоичного вывода. Но в этот момент количество выходных символов увеличивается до 31! (Один меньше, чем [вероятно] число бит в вашем int, потому что последний бит будет переключать номер, отрицательного. Вам нужен отдельный код для обработки отрицательных чисел.)

Он работает как есть для всех баз < = 10 (включая само основание «10»).Если вы хотите расширить тот же код для обработки баз данных> 10, например, «двенадцатеричный» (базовый 12) или шестнадцатеричный (базовый 16), вам необходимо изменить линию printf. Это заставит ваш код работать до основания 36 («sexatrigesimal»). За конвенции, «цифра» выше, чем 9 написана A, B, C и так далее:

while (--length >= 0) 
    printf ("%c", storage[length] < 10 ? storage[length]+'0' : storage[length]+'A'-10); 

(Как я выдумываю, как я пишу, я использовал трехкомпонентную оператора ?..:.. для удобства, а не отдельный if..else, который нуждается в большем наборе текста. (OTOH, добавление комментария отрицает усиление. О, хорошо, по крайней мере, вы узнали о тройном операторе, а также имена для нескольких базовых чисел.))


Другим решением является использование рекурсия. Это полезный метод, потому что ему не нужно выделять некоторое пространство в памяти - вместо этого он полагается на стек внутренних вызовов.

Принцип заключается в том, что вы пишете функцию, которая печатает только последнюю цифру вашего номера - но перед тем это, что, если остаток равен 0, это вызывает сам с остатком числа ,

Таким образом, функция вызывает себя, а затем печатает номер, который должен. Поскольку он сначала называет себя, , получивший название, печатает номер, который он должен - один слева цифры в «оригинальной» функции. И так далее и т. Д., Пока не будет напечатано никаких цифр. С этого момента последняя вызываемая функция печатает свой номер (который является самой левой цифрой), возвращается к функции, из которой она была вызвана, которая, в свою очередь, печатает свой номер (еще один справа), вплоть до первоначальный вызов.

Рекурсия - это довольно крутое умение овладеть, так что попробуйте это!

1

Вот две удобные функции, которые могут быть полезны. Они возвращают строку для каждого из преобразований. Подобным же образом ответ igleyy.

string toOctalFromDecimal (int num) { 
    ostringstream o; 
    o << std::oct << num; 
    return o.str(); 
} 

string toDecimalFromOctal (int num) { 
    std::ostringstream o; 
    int x; 

    std::istringstream(to_string(num)) >> std::oct >> x; 
    o << std::dec << x; 
    return o.str(); 
} 
Смежные вопросы