Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Написание собственного класса String 
V
    Опции темы
maxxi
Дата 5.11.2008, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 22.4.2007

Репутация: нет
Всего: нет



Пишу  для лабы написать собственный класса String.
Нужно написать в нем методу convertStrToInt, то есть перевод String в integer.

В одной методичке наткнулся на  такой код непонятного содержания : 

Код

int MyStr::convertStrToInt(char* p_str) {
  int res = 0;
  int a;
  int temp_power = 0;
  if (p_str != NULL) {
   for (int i=(getLength(p_str)-2); i >= 0; i--) {
      if ((p_str[i] >= '0') && (p_str[i] <= '9')) {
        a = (((int) p_str[i])- 48);
        if (temp_power == 9) {
          if (a == 2) {
            if (res<=147483647) {
              res+=( a * power(10, temp_power));

            }
            else {
                 return -1;
            }
          }
          else {
               if (a < 2) {
                     res+=( a * power(10, temp_power));
               }

               else {
                    return -1;
               }
          }
        }
        else {
          if (temp_power > 9) {
                         return -1;
          }
          else {
               res+=( a * power(10, temp_power));
          }
        }        
      }
      else {
        return -1;
      }
      temp_power++;
    }
    return res;
  }
  else {
    return -1;
  }
}

int MyStr::power(int x, int n) {
  int res = 1;        
  for (int i=0; i<n; i++) {
    res*=x;
  }
  return res;
}






Обьясните ,пожайлуста, что выполняет выделенный в нем кусок.

Спасибо

Это сообщение отредактировал(а) maxxi - 5.11.2008, 00:35
PM MAIL   Вверх
Dmi3ev
Дата 5.11.2008, 01:39 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41



Код

   for (int i=(getLength(p_str)-2); i >= 0; i--) {
      if ((p_str[i] >= '0') && (p_str[i] <= '9')) {
        a = (((int) p_str[i])- 48);


в первой строке мы говорим, что будем двигаться от конца строки к началу, перебирая все символы.
во второй строке мы смотрим, можно ли вообще преобразовывать в цифру симол, вдруг там буква.
в третьей строке мы узнаем что за цифра, только замысловатым способом, дело в том, что символ "0" имеет код 48, "1"  49 и тд, так что допустим у нас символ p_str[i]= '0', тогда (int)p_str[i]=48, тогда а=48-48=0, вот мы и преобразовали символ в цифру, теперь надо ее поставить на свое место.
Код

            if (res<=147483647) {
              res+=( a * power(10, temp_power));

этот код делает следующее, нашу цифру умножает на 10 в степени temp_power, или другими словами ставит ее на свое место, те если у нас строка "123" тогда после первого прохода по циклу res=3 далее он возьмет 2, умножит на 10 в степени 1, затем увеличит res на эту величину и res=23, потом возьмет 1, умножит на 10 в степени 2 и увеличит res на 100, res=123


--------------------

PM MAIL   Вверх
maxxi
Дата 5.11.2008, 08:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 22.4.2007

Репутация: нет
Всего: нет



Большое спасибо, все стало понятно 
PM MAIL   Вверх
mes
Дата 5.11.2008, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата
a = (((int) p_str[i])- 48);

48 лучше оставить символом.
Код

а = static_cast<int>(p_str[i]-'0');


Это сообщение отредактировал(а) mes - 5.11.2008, 11:36


--------------------
PM MAIL WWW   Вверх
mes
Дата 5.11.2008, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Код


int StrToInt (const char* str )
{
    int res =0;  
// тут можно добавить проверку на знак;

    while (*str)  // пока не дойдем до конца строки
    {
          if ( (*str) >= '0') && ( (*str) <= '9'))            // если число
          {
//          тут можно добавить проверку на переполнение res

               res *=10;                                 // сдвигаем результат влево на одну позицию 
               res += static_cast<int>( (*str)-'0');     //  и занимаем последнюю позицию нашим числом
          }
          else                // если встретилось не-число 
                 return 0; // возвращаем 0 или  заменить на return res; если нужно число до первого не-числового символа  

         ++str; // переходим к следующему символу.
    }
   return res;           // возвращаем результат.
};

Тут не хватает проверки на переполнение res, определения знака числа и возвращения кода ошибки. Удачи  smile 


Это сообщение отредактировал(а) mes - 7.11.2008, 01:52


--------------------
PM MAIL WWW   Вверх
Dmi3ev
Дата 5.11.2008, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41



а я бы для понимания посоветовал вот так вот переводить символ в цифру (для начала):
Код

int chtodig (char a)
{
int res;
switch ((int) a)
 {
  case 48: res=0; break;
  case 49: res=1; break;
  case 50: res=2; break;
  case 51: res=3; break;
  case 52: res=4; break;
  case 53: res=5; break;
  case 54: res=6; break;
  case 55: res=7; break;
  case 56: res=8; break;
  case 57: res=9; break;
 }
return (res);
}

что-то вроде этого.
а в степень возводить вот так:
Код

double power(double z, int x)
{
double r=1;
if (x==0)
 {
  return 1;
 }
else
 {
  if (x>0)
   {
    for (int j=1; j<=x; j++)
     {
      r=r*z;
     }
    return (r);
   }
  else
   {
    for  (int k=-1; k>=x; k--)
     {
      r=r/z;
     }
    return (r);
   }
 }
}

просто, как вариант.


--------------------

PM MAIL   Вверх
mes
Дата 5.11.2008, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Dmi3ev @  5.11.2008,  13:54 Найти цитируемый пост)
а я бы для понимания посоветовал вот так вот переводить символ в цифру (для начала):

и вот опять магические цифры ...  мне кажется в таком виде Ваш код, как минимум, будет меньше напрягать:
Код

switch (a)
 {
  case '0': res=0; break;
  case '1': res=1; break;
  case '2': res=2; break;
  case '3': res=3; break;
  case '4': res=4; break;
  case '5': res=5; break;
  case '6': res=6; break;
  case '7': res=7; break;
  case '8': res=8; break;
  case '9': res=9; break;
 }

не правда ли ?  smile 

Это сообщение отредактировал(а) mes - 5.11.2008, 17:29


--------------------
PM MAIL WWW   Вверх
kurtis
Дата 5.11.2008, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



А чем atoi() плох? Зачем пиать то что уже есть? Задача я так понял ставится конкретно в реализации самого класса Стринг, а не в реализации какого-то конкретного метода.
PM MAIL   Вверх
maxxi
Дата 7.11.2008, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 22.4.2007

Репутация: нет
Всего: нет



Цитата(kurtis @ 5.11.2008,  18:08)
А чем atoi() плох? Зачем пиать то что уже есть? Задача я так понял ставится конкретно в реализации самого класса Стринг, а не в реализации какого-то конкретного метода.

atoi() cказали нельзя использовать....самим писать надо


Это сообщение отредактировал(а) maxxi - 7.11.2008, 00:54
PM MAIL   Вверх
baldina
Дата 7.11.2008, 01:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата

res +=10; // сдвигаем результат влево на одну позицию


странно. "123" превращается в 36 ;)

так правильно:
Код


int StrToInt (const char* str)
{
  int res=0;
  bool negate = false;
  if (*str == '-')
  {
      negate = true;
      ++str;
  }
      
  // пока в строке цифры
  while ('0' <= *str && *str <= '9')  
  {
    // без проверки на переполнение
    res *=10;       // сдвигаем результат влево на один десятичный разряд 
    res += *str-'0';//  и заполняем последний разряд текущей цифрой
    ++str;          // переходим к следующему символу.
  }

  return negate ? -res : res;       // возвращаем результат.
}



PM MAIL   Вверх
mes
Дата 7.11.2008, 01:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(baldina @  7.11.2008,  01:16 Найти цитируемый пост)
res +=10; // сдвигаем результат влево на одну позицию

sorry опечатка.. там умножить , так как сдвиг и есть умножение. сейчас исправлю..



--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0822 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.