Перевод из любой системы счисления в любую с++

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

uncontrol1
Сообщения: 11
Зарегистрирован: 27 дек 2015, 10:09

нужно чтоб до 16-ричной работала хотя бы

Код: Выделить всё

#include <iostream>

using namespace std;

//Функция возвращающая переведенное число
char* ConvertCC(char* x,int fromCC,int toCC){
    //Таблица символов исходного числа для
    //определения их порядкового номера
    char *abc="0123456789ABCDEFGHIJKLMNOPQESTUVWXYZ";
    //Промежуточная строка
    char buf[255]={0};
    //Результирующая строка
    char *result;

    int i //Это количество символов в начальном числе
       ,k //Это будет порядковым номером очередного символа в входном числе
       ,ten=0 //Это будет его аналог в 10-чной системе
       ,stp=1; //А это просто степень для перевода в 10-чную
    //Узнаем сколько символов во входящем числе
    for(i=0;x[i];i++);
    //А потом с последнего символа начинаем переводить
    for(;i;i--){
        //Выясняем его порядковый номер
        for(k=0;abc[k]!=x[i-1] && k<36;k++);
        //Умножаем его на степень, прибавляя к результирующему числу
        // в 10-тиричной системе
        ten+=k*stp;
        //И повышаем степень для следующего символа
        stp*=fromCC;
    }
    //После обратной формулой
    k=0;
    while(ten){
     //Получаем цифры числа в нужной системе
     i=ten % toCC;
     //И пишем их в буфер
     buf[k++]=abc[i];
     //Деля число на основание результирующей системы
     ten/=toCC;
    }
    //Поскольку число у нас в буффере верх ногами
    //Создаем результирующую переменку
    result=new char[k+1];
    //В которую пишем результат в его естесственном виде
    for(i=0;k;i++) result[i]=buf[--k];
    //Маркеруем конец строки нулем
    result[i]=0;
    //И возвращаем
    return result;

}

int main()
{
    char* s=ConvertCC("B12",20,16);
    cout<<s;
    delete s;
    cin.get();
    return 0;
}
помогите исправить код
нужен ввод систем с клавиатуры
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Код: Выделить всё

//Выясняем его порядковый номер
        for(k=0;abc[k]!=x[i-1] && k<36;k++);
А почему -1?

Код: Выделить всё

//Умножаем его на степень, прибавляя к результирующему числу
        // в 10-тиричной системе
        ten+=k*stp;
В десятичную ты ещё не перевёл.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Сионист писал(а):А почему -1?

Потому, что после предыдущего цикла i - это индекс не последнего символа, а терминирующего нуля.
Сионист писал(а):В десятичную ты ещё не перевёл.
Ты на кривой коммент не смотри. В этом цикле как раз перевод в десятичную происходит, и он правильный, вроде как.

Сионист, ты либо, если берёшься помогать, то до конца разбирайся, либо вообще ничего не пиши. А то только человека с толку сбиваешь.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Romeo писал(а):Потому, что после предыдущего цикла i - это индекс не последнего символа, а терминирующего нуля.
А не логичней один раз исправить это декрементом, чем каждый раз вычитать единицу?
Ты на кривой коммент не смотри. В этом цикле как раз перевод в десятичную происходит, и он правильный, вроде как.
Да ну! Там вообще то перевод во внутреннее представление, то есть в двоичную систему.
//Поскольку число у нас в буффере верх ногами
Зачем? Количество исходных цифр известно, логарифм одного основания по другому проблем тоже не вызваает, значит можно вычислить количество цифр в переводе. Что мешает вычислить позицию младшей цифры и заполнять буфер от этой позиции к началу буфера?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Вроде бы функция перевода написана правильно, по крайней мере грубых поверхностных ошибок я не вижу, да и пара запущенных тестов дали правильный результат. Если проблема только в том, чтобы сделать ввод с клавиатуры, то это можно сделать так:

Код: Выделить всё

#include <iostream>
#include <string>

using namespace std;

//Функция возвращающая переведенное число
char* ConvertCC(const char* x,int fromCC,int toCC){
    //Таблица символов исходного числа для
    //определения их порядкового номера
    static const char abc[]="0123456789ABCDEFGHIJKLMNOPQESTUVWXYZ";
    //Промежуточная строка
    char buf[255]={0};
    //Результирующая строка
    char *result;

    int i //Это количество символов в начальном числе
       ,k //Это будет порядковым номером очередного символа в входном числе
       ,ten=0 //Это будет его аналог в 10-чной системе
       ,stp=1; //А это просто степень для перевода в 10-чную
    //Узнаем сколько символов во входящем числе
    for(i=0;x[i];i++);
    //А потом с последнего символа начинаем переводить
    for(;i;i--){
        //Выясняем его порядковый номер
        for(k=0;abc[k]!=x[i-1] && k<36;k++);
        //Умножаем его на степень, прибавляя к результирующему числу
        // в 10-тиричной системе
        ten+=k*stp;
        //И повышаем степень для следующего символа
        stp*=fromCC;
    }
    //После обратной формулой
    k=0;
    while(ten){
     //Получаем цифры числа в нужной системе
     i=ten % toCC;
     //И пишем их в буфер
     buf[k++]=abc[i];
     //Деля число на основание результирующей системы
     ten/=toCC;
    }
    //Поскольку число у нас в буффере верх ногами
    //Создаем результирующую переменку
    result=new char[k+1];
    //В которую пишем результат в его естесственном виде
    for(i=0;k;i++) result[i]=buf[--k];
    //Маркеруем конец строки нулем
    result[i]=0;
    //И возвращаем
    return result;
}

int main()
{
    int fromCC;
    cout << "Enter From CC: ";
    cin >> fromCC;

    int toCC;
    cout << "Enter To CC: ";
    cin >> toCC;

    cout << "Enter number: ";
    string str;
    cin >> str;

    char* s = ConvertCC(str.c_str(), fromCC, toCC);
    cout << "Result is: " << s << endl;
    delete s;

    cin.get();
    return 0;
}
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Сионист писал(а):А не логичней один раз исправить это декрементом, чем каждый раз вычитать единицу?
Это уже второй вопрос, но алгоритм верный.
Сионист писал(а):Да ну! Там вообще то перевод во внутреннее представление, то есть в двоичную систему.
Ну можно и так сказать, но, опять-таки, алгоритм тут верный, так что придирки излишни.
Сионист писал(а):Зачем? Количество исходных цифр известно, логарифм одного основания по другому проблем тоже не вызваает, значит можно вычислить количество цифр в переводе. Что мешает вычислить позицию младшей цифры и заполнять буфер от этой позиции к началу буфера?
Ой, там можно легко влететь на ошибку на округлениях и либо не досчитаться одного символа, либо пересчитаться. Использованный способ, с промежуточным буфером мне и самому как-то ближе. Даже если не учитывать возможные ошибки на округлениях, можно привести более веский аргумент - это быстродействие. Создание буфера на стеке - это всего одна целочисленная операция (add ebp, sizeof(buff)), в то время, как для вычисления логарифма, придётся два раза вызвать функцию log (а каждый вызов - это апроксимация рядом Маклорена и вычисление суммы сходящегося ряда) и последующее вычисление частного результатов этих двух вызовов.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Алгоритм у него пессимизированный. И к тому же недообфускированный: уж если i - позиция текущей цифры, то проще уж сделать так, чтоб она везде была позицией текущей цифры, а не соседнего с ней символа. И комментарии кривые. Например, k - это на самом деле числовое представление цифры, а не позиция её в числе.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Ну это всё мелочи, на самом деле. Мне вот куда больше не нравится возврат указателя, которому снаружи нужно делать delete. Но главное, что код работает: это редкость для студенческих задачек.

Кстати, что такое пессимизированный алгоритма, я не понял. Что ты подразумеваешь под этим словом? Гугл подсказывает, что слово "пессимизированный" всегда используется со словом "сайт" и обозначает понижение позиции сайта в выдаче поисковика. И других значений у слова, похоже, нет. Как это можно прикрутить к слову "алгоритм", не представляю.

А слово недообфуксированный ты, вообще, похоже, изобрёл на ходу и вставил непонятно зачем. Если его перевести со всеми приставками, то получится "сделанный недостаточно запутанным". Зачем алгоритм запутывать и почему степень запутанности настолько важна, что ты призываешь его запутать ещё сильнее - это для меня остаётся загадкой.

Или ты просто умничаешь? :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Но главное, что код работает: это редкость для студенческих задачек.
Если работоспособность первой версии студенческой поделухи - редкость, это нормально. Если работоспособность такой поделухи - вообще редкость, кол надо ставить не студентам, а преподавателю.
Кстати, что такое пессимизированный алгоритма, я не понял. Что ты подразумеваешь под этим словом? Гугл подсказывает, что слово "пессимизированный" всегда используется со словом "сайт" и обозначает понижение позиции сайта в выдаче поисковика.
Оптимизировать и пессимизировать можно всё, что имеет хоть какие то критерии оптимальности.
А слово недообфуксированный ты, вообще, похоже, изобрёл на ходу и вставил непонятно зачем. Если его перевести со всеми приставками, то получится "сделанный недостаточно запутанным". Зачем алгоритм запутывать и почему степень запутанности настолько важна, что ты призываешь его запутать ещё сильнее - это для меня остаётся загадкой.
Я не призываю запутывать, а лишь вижу неудачную попытку это сделать.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Сионист писал(а):Если работоспособность первой версии студенческой поделухи - редкость, это нормально
Это не просто поделуха. Я честно скажу, мне этот код нравится. Пускай он не блещет суперпримочками и переменные в нём имеют неосмысленные имена, но зато он лаконичен и достаточно оптимален. Если это первый код человека, то он далеко пойдёт.
Сионист писал(а):Оптимизировать и пессимизировать можно всё, что имеет хоть какие то критерии оптимальности.
Так что а что такое "пессимизированный алгоритм"? Я такого термина не встречал, да и гугл тоже офигевает от такого запроса. Подсказывает, может я имел в виду "оптимизированный алгоритм". Кинь ссылочку, пожалуйста, почитать.

И про недообфускированный тоже поясни. Что такое фускация строк - знаю. Что такое фускация промежуточного кода, тоже. А вот недообфускированность алгоритма... первый раз слышу.

(дописано после редактирования сообщения Сионистом)
Сионист писал(а):Я не призываю запутывать, а лишь вижу неудачную попытку это сделать.
Тогда, как минимум, приставка "не" лишняя.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить