Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как разобрать число на цифры ?


Автор: Frog 16.12.2006, 05:19
Здравствуйте господа! мне необходимо разобрать число на массив из состовляющих его цифр. 

К примеру: 

из
int а = 5432;
должен получиться массив
int ма[] = {5,4,3,2};

В джаве я делал так - преобразовывал int 'а' в строку , строку парсил, результатами набивал массив. Но во первых это возможно, не лучший способ даже для джавы , а во вторых в С я новичек , и как мне кажеться, тот subset языка который я сейчас изучаю (win32 для КПК) вообще "не понимает" строк и операций с ними... Посоветуйте что можно сделать - пожалуйста.

Автор: witex 16.12.2006, 06:04
Вот поделился, что сам делал по учёбе.. не знаю уж и когда.
Код

#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void main()
{
    int a,b,count,sum;
cout << " Vvedite naturaljnoe 4islo ";
cin >> a;
b=a;
count=0;
sum=0;
while(a>0)
{
    count++;
sum = sum+(a%10);
a/=10;
}
int *ch=new int[count-1];
a=count;
while(b>0)
{
    
ch[a-1] = b%10;
b/=10;
a--;
}
cout << "Koli4estvo cifr " << count <<endl;
cout << " Summa 4isel ravna " << sum <<endl;
for(a=0;a<count;a++)
cout << ch[a] << endl;
getch();
}

Автор: MAKCim 16.12.2006, 11:04
Код

void convert(int numb, string& str) {
    if (numb / 10 > 0) convert(numb / 10, str);
    str += static_cast<char>((numb % 10) + 48);
}

Автор: Anikmar 16.12.2006, 11:21
Цитата(MAKCim @ 16.12.2006,  11:04)
Код

void convert(int numb, string& str) {
    if (numb / 10 > 0) convert(numb / 10, str);
    str += static_cast<char>((numb % 10) + 48);
}

Я так понял, что нужно избегать строк.

Пример writex разумный, но:
Динамическое определение массива мне видится через чур сильным наворотом - сэкономленные несколько байт съедаются лишним кодом.
Не проще ли массив задать статически - в данном случае не вижу особой проблемы.

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

Автор: anwe 16.12.2006, 13:05
Так это простой алгоритм. Допустим для десятичного числа оно разбивается на тысячи, сотни, десятки и единицы. Вот и дели на них (без перевода строки): 1573=1*1000+5*100+7*10+3.
Целое от деление - будет целым, то есть твоей цифрой, а остаток делишь на 10 в степени на 1 меньше. И так дальше.

Автор: GIK 16.12.2006, 13:47
Цитата

while(a>0)
{
    count++;
sum = sum+(a%10);
a/=10;
}
int *ch=new int[count-1];
a=count;
while(b>0)
{
    
ch[a-1] = b%10;
b/=10;
a--;
}

А я вот чето вообще не вкурю этот алгоритм smile 
В первом цикле не понятно почему собирается сумма остатков от деления. Потом создается массив длинной меньше на один чем кол-во итераций. Во втором цикле, с самого начала,обращаются зачем то вообще на индекс превышающий длину массива??? И походу переменная а  ни когда не дойдет до <0?

Цитата

for(a=0;a<count;a++)
cout << ch[a] << endl;
getch();
}
и как после этого получается нужный результат?


Блин, вообще не пойму smile 

Автор: Daevaorn 16.12.2006, 13:51
Цитата(Frog @  16.12.2006,  06:19 Найти цитируемый пост)
тот subset языка который я сейчас изучаю (win32 для КПК) вообще "не понимает" строк и операций с ними... 

Что за subset, интересно?

Автор: Anikmar 16.12.2006, 14:12
Цитата

А я вот чето вообще не вкурю этот алгоритм  
В первом цикле не понятно почему собирается сумма остатков от деления. Потом создается массив длинной меньше на один чем кол-во итераций. Во втором цикле, с самого начала,обращаются зачем то вообще на индекс превышающий длину массива??? И походу переменная а  ни когда не дойдет до <0?


Мне показалось, что sum это рудимент от какого-то другого алгоритма.
Первый цикл считает количество циферок, чтобы узнать размер массива под них.

Автор: GIK 16.12.2006, 14:33
Все, догнал  smile 

Автор: witex 16.12.2006, 16:16
Да делал алгоритм, для сдачи в колледже! 
Надо было разбить по цыфрам, найти их количесвто и сумму чисел.

GIK, "а" и не будет меньше 0, чтобы оборвать цикл достаточно чтобы "а" был равен 0.
Anikmar, знаю что особого смысла динамический массив делать! тогда и одного цикла хватит! ПРото размер, нормальный задать и всё!
Главное что работает! и что бы Frog понял!

Автор: MAKCim 16.12.2006, 16:41
Цитата

Я так понял, что нужно избегать строк.

Код

void convert(int numb, char** str) {
    if (numb / 10 > 0) convert(numb / 10, str);
    **str = (char)((numb % 10) + 48);
    ++*str;
}

Автор: zabivator 16.12.2006, 17:01
Код

#include <vector>
#include <iostream>

void convert( int number, std::vector<int>& result )
{
   while( number != 0 )
   {
       int current_number = number % 10;
       result.push_front(  current_number );
       number -= current_number;
       number /= 10;
   }
}

int main( argc, argv*[] )
{
   vector<int> result;
   convert( 12312, result );
   unsigned s = result.size();
   for ( i = 0; i < s; ++i )
      std::cout<<s<<std::endl;
   return 0;
}

Автор: witex 16.12.2006, 17:13
zabivator, ты чё издеваешься? зачем тут вектор? это же чистое извращение! Он дольще будет работать чем мои ва цикла, в 2 раза! Не надо так издеваться!

Автор: FelikZ 16.12.2006, 17:25
Да, пожалуй вектор тут точно ненадо юзать!
Вариант witex'а самый гуманный smile 

Автор: witex 16.12.2006, 17:30
Вопрос решён. Хотя коментов, самого автора не видели.
Но всё же,хватит пустые димагогии разводить! Закрывайте тему.

Автор: Frog 16.12.2006, 21:16
Как автор темы я хочу поблагодарить уважаемых участников обсуждения ! я все-таки решил оставить свою старую схему с парсингом (ведь я  портирую код - проще оставить отработанный способ), тем более что можно удобно подразбить число на массив из символов. 

int num = 5432;
char myBuf[4];
sprintf(myBuf, "%i\0", num);

Еще раз огромное спасибо всем!

Автор: comp 17.12.2006, 07:37
Слегка поздно конечно... но, помоему, решение witex'a, в любом случае, не очень. Отдельный цикл только лишь для того, чтобы съэкономить пару байт, когда наше число в длину не превышает 20, по-моему, не самый лучший выход. Как бы я делал.

int* parse(long long num)
{
       int res[20];
       int id = 0;

       for (; num > 0; num /= 10)
            res[id++] = num % 10;

       return res;
}

Автор: MAKCim 17.12.2006, 11:01
comp
число у тебя задом наперед запишется  smile 
кроме того - возвращать указатель на данные во фрейме функции (т. е в стеке)  smile 
вообщем низачет

Автор: comp 17.12.2006, 12:06
MAKCim, Я всё прекрасно понимаю. Это лишь так, черновик, пример, не более.

Автор: witex 17.12.2006, 12:50
comp,  ну и смысл, демагогии разводить вопрос решён. Объяснил! Делал в колледж! Там их не волнует как да что!  Да и делал! пол гоа назад! чисто скопировал и вставил! Не глядя! Тогда я шибко в скорость не вдавался! Ты на zbivatora код посмотри! Мой код довольнотаки удобный и быстрый! А векторы не зачем! 
Вопрос решили, и сам автор по своему решил, чего тогда ещё чёто придумывать? Как минимум по твоему агоритму прийдёться реверсировать массив, значит опять цикл! Чем лудше?

Frog закрывай тему.


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)