Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.65/37: Рейтинг темы: голосов - 37, средняя оценка - 4.65
CEO SOVAZ Corp.
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1
1

Моя реализация функции перевода string в int

21.12.2012, 18:23. Показов 7302. Ответов 57

Author24 — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <string>
 
using namespace std;
 
int str_to_int(string a);
 
int main() {
    string s = "-4789";
    cout << str_to_int(s);
}
 
int str_to_int(string a) {
    int num = 0;
    int tmp;
    bool anti = false;
 
    for(int i = a.size() - 1, l = 1; i >= 0; --i, l *= 10) {
        if(a[i] == '0') {tmp = 0;}
 
        else if(i == 0 && a[i] == '-') {anti = true;}
 
        else if(a[i] == '1') {tmp = 1;}
        else if(a[i] == '2') {tmp = 2;}
        else if(a[i] == '3') {tmp = 3;}
        else if(a[i] == '4') {tmp = 4;}
        else if(a[i] == '5') {tmp = 5;}
        else if(a[i] == '6') {tmp = 6;}
        else if(a[i] == '7') {tmp = 7;}
        else if(a[i] == '8') {tmp = 8;}
        else if(a[i] == '9') {tmp = 9;}
 
        else {
                return 0;
        }
 
        num += (tmp * l);
    }
 
    if(anti == true) {return -num;}
    else {return num;}
}


P.S. Пишите предложения по улучшению этой функции

Добавлено через 5 минут
Актуальна

Добавлено через 5 минут
Вверх
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.12.2012, 18:23
Ответы с готовыми решениями:

Моя реализация функции перевода STRING в DOUBLE
#include &lt;iostream&gt; #include &lt;string&gt; using namespace std; double str_to_double(string a); ...

Реализация функции char *padl(const char *string, int len, int c=' ')
Реализовать функцию возвращающую указатель на новую строку длины len, полученную из string либо...

Моя реализация алгоритма перевода числа в пропись (русский язык)
Добрый день.Недавно передо мной стояла задача сделать REST сервис перевода числа в пропись(на...

Too few parameters in call to 'Lechebnica::AddNewElement(int,int,string,string,int,string)
Edit1 Id Edit2 Имя Edit3 Фамилия Edit4 Номер телефона ComboBox1 Услуга ...

57
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
22.12.2012, 05:29 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от fit Посмотреть сообщение
не "окружается нулями". что там за границами зарезервированной new области - черт его знает.
Как минимум есть такая штука (по крайней мере в VS) как guard bytes - некоторые магические значения, которые добавляются до и после выделенной в куче памяти в дебаге. Первый байт этого значения вполне может быть нулём. И тогда нуль-терминал у строки есть, всё вроде хорошо - в дебаге) А в релизе будет access violation (или что-нибудь в этом роде).
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
22.12.2012, 11:17 22
Цитата Сообщение от fit Посмотреть сообщение
не "окружается нулями". что там за границами зарезервированной new области - черт его знает.
ты когда нибудь дизасемблировал Debug версию?
как же по твоему отлавливать выход за пределы памяти
а самый главный аргумент
atoi принимает строку
у ТС работает эта конструкция
C++
1
2
char* ch = new char(a[i]);
tmp = atoi(ch);
значит после памяти есть 0 и ch волшебным образом превращается в строку

Цитата Сообщение от fit Посмотреть сообщение
к тому же, atoi получит ровно столько, сколько зарезервировал new.
а откуда он знает сколько зарегистрировал new?
а если я так напишу
C++
1
2
3
4
5
6
7
char *buf=new char[5];
buf[0]='5';
buf[1]='3';
buf[2]=0;
buf[3]='6';
buf[4]='7';
int m=atoi(buf);
сколько будет m?

а если статическую строку дам?
0
CEO SOVAZ Corp.
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1
22.12.2012, 11:27  [ТС] 23
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
 
using namespace std;
 
int str_to_int(string a);
 
int main() {
    string s = "-7868";
    cout << str_to_int(s);
}
 
int str_to_int(string a) {
    int num = 0;
    int tmp;
    bool anti = false;
    double l = 1;
 
    for(int i = a.size() - 1; i >= 0; --i, l *= 10) {
        if(a[i] == '0') {tmp = 0;}
 
        if(a[i] >= '0' && a[i] <= '9') {tmp = a[i] - '0';}
 
        else if(i == 0 && a[i] == '-') {anti = true; break;}
 
 
        else {
                return 0;
        }
 
        num += (tmp * l);
    }
 
    if(anti == true) {return -num;}
    else {return num;}
}
P.S. Чтобы было видно

Добавлено через 8 минут
Вверх
0
433 / 368 / 149
Регистрация: 06.08.2012
Сообщений: 961
22.12.2012, 12:37 24
Я так сделал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
 
int StrToInt(std::string);
 
int main()
{
    std::cout << StrToInt("1995") << std::endl;
 
    system("PAUSE");
    return 0;
}
 
int StrToInt(std::string str)
{
    int convert_str = 0;
    std::string str_n = "0123456789";
 
    for (int i = 0; i < str.size(); i++) {
        for (int cnt = 0; cnt < 10; cnt++)
            if (str[i] == str_n[cnt]) 
                convert_str = convert_str * 10 + cnt;
    }
    if (str[0] == '-') return -convert_str;
    else return convert_str;
}
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
22.12.2012, 12:40 25
Цитата Сообщение от SeregaC++ Посмотреть сообщение
Я так сделал:
И сколько раз у тебя будет крутится этот цикл
Цитата Сообщение от SeregaC++ Посмотреть сообщение
for (int cnt = 0; cnt < 10; cnt++)
* * * * * * if (str[i] == str_n[cnt])
при числе 999 999
0
CEO SOVAZ Corp.
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1
22.12.2012, 12:41  [ТС] 26
Цитата Сообщение от SeregaC++ Посмотреть сообщение
#include <iostream>
int StrToInt(std::string);
int main()
{
* * std::cout << StrToInt("1995") << std::endl;
system("PAUSE");
* * return 0;
}
int StrToInt(std::string str)
{
* * int convert_str = 0;
* * std::string str_n = "0123456789";
for (int i = 0; i < str.size(); i++) {
* * * * for (int cnt = 0; cnt < 10; cnt++)
* * * * * * if (str[i] == str_n[cnt])
* * * * * * * * convert_str = convert_str * 10 + cnt;
* * }
* * if (str[0] == '-') return -convert_str;
* * else return convert_str;
}


P.S. Вы, наверное, единственный человек, кто это увидел и в БЛОГЕ, и ЗДЕСЬ
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
22.12.2012, 12:41 27
а как отобразится число 123вася123 ?
0
CEO SOVAZ Corp.
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1
22.12.2012, 12:45  [ТС] 28
Все эти программы работают достаточно быстро (но моя быстрей в 10 раз, потому что один цикл )
Сложность моей - O(длина строки);
Сложность SeregaC++ - O(длина строки X 10)
0
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
22.12.2012, 12:47 29
Цитата Сообщение от sovaz1997 Посмотреть сообщение
O(длина строки X 10
только это как бы равно
Цитата Сообщение от sovaz1997 Посмотреть сообщение
O(Длина строки)
И вообще, зачем вы пишите все эти велосипеды? Попробуйте написать функцию, которая переводит из любого типа в любой(ну или выдает ошибку компиляции, если это невозможно). Она пишется в ~5 строк.
0
CEO SOVAZ Corp.
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1
22.12.2012, 12:48  [ТС] 30
SeregaC++, зачем ты переделал мою программу в худшую сторону
Цикл внутри цикла удлинит время работы программы на порядок. Чем тебе не нравится сравнение:
C++
1
if(a[i] >= '0' && a[i] <= '9') {tmp = a[i] - '0';}
Вместо этого ты зачем-то вставил цикл...
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
22.12.2012, 12:48 31
Цитата Сообщение от sovaz1997 Посмотреть сообщение
Сложность SeregaC++ - O(длина строки X 10)
это не самое главное (хотя тоже не маловажно)
скорми его алгоритму вот это

Цитата Сообщение от ValeryS Посмотреть сообщение
а как отобразится число 123вася123
и он вернет 123123
нет анализ на недопустимость
0
CEO SOVAZ Corp.
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1
22.12.2012, 12:49  [ТС] 32
Цитата Сообщение от diagon Посмотреть сообщение
только это как бы равно
Почему? - ведь цикл проходит 10 раз, а мой if только сравнивает?
P.S. Или я что-то не понимаю?
0
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
22.12.2012, 12:50 33
Цитата Сообщение от sovaz1997 Посмотреть сообщение
P.S. Или я что-то не понимаю?
Именно так.
У вас будет меньше константа, но сложность-то одинаковая.
0
433 / 368 / 149
Регистрация: 06.08.2012
Сообщений: 961
22.12.2012, 12:55 34
Цитата Сообщение от sovaz1997 Посмотреть сообщение
Все эти программы работают достаточно быстро (но моя быстрей в 10 раз
Твоя.
Моя.

Ну не в 10 раз.
0
CEO SOVAZ Corp.
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1
22.12.2012, 13:27  [ТС] 35
P.S. Я еще проверил память - моя побольше 720кб, а твоя 712кб. Это потому, что я по ссылке не передаю string и в одном месте использую тип double, а не int

Добавлено через 3 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>
 
using namespace std;
 
int str_to_int(string& a);
 
int main() {
    string s = "-768";
    cout << str_to_int(s);
    cin.get();
}
 
int str_to_int(string& a) {
    int num = 0;
    char tmp;
    bool anti = false;
    int l = 1;
 
    for(int i = a.size() - 1; i >= 0; --i, l *= 10) {
        if(a[i] == '0') {tmp = 0;}
 
        if(a[i] >= '0' && a[i] <= '9') {tmp = a[i] - '0';}
 
        else if(i == 0 && a[i] == '-') {anti = true; break;}
 
 
        else {
                return 0;
        }
 
        num += (tmp * l);
    }
 
    if(anti == true) {return -num;}
    else {return num;}
}
Улучшил работу с памятью

Добавлено через 10 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
 
using namespace std;
 
int str_to_int(string& a);
 
int main() {
    string s = "-68";
    cout << str_to_int(s);
    cin.get();
}
 
int str_to_int(string& a) {
    int num = 0;
    char tmp;
    int l = 1;
 
    for(char i = a.size() - 1; i >= 0; --i, l *= 10) {
        if(a[i] == '0') {tmp = 0;}
 
        if(a[i] >= '0' && a[i] <= '9') {tmp = a[i] - '0';}
 
        else if(i == 0 && a[i] == '-') {break;}
 
 
        else {
                return 0;
        }
 
        num += (tmp * l);
    }
 
    if(a[0] == '-') {return -num;}
    else {return num;}
}
Теперь программа занимает 708 КБ ОЗУ. Достигнута высшая оптимизация (как и в настоящей ф-ии atoi())

Добавлено через 14 минут
Вверх
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
22.12.2012, 13:28 36
Цитата Сообщение от sovaz1997 Посмотреть сообщение
Теперь программа занимает 708 КБ ОЗУ. Достигнута высшая оптимизация
тебе до оптимизации еще пахать и пахать
например при каждой итерации проверяем
Цитата Сообщение от sovaz1997 Посмотреть сообщение
else if(i == 0 && a[i] == '-')
значит надо вынести за цикл
Цитата Сообщение от sovaz1997 Посмотреть сообщение
if(a[i] == '0') {tmp = 0;}
зачем это сравнение которое дублирует следующая строчка

Цитата Сообщение от sovaz1997 Посмотреть сообщение
if(a[i] >= '0' && a[i] <= '9') {tmp = a[i] - '0';}
0
512 / 464 / 81
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
22.12.2012, 13:29 37
А зачем для нуля отдельная проверка?
C++
1
if(a[i] == '0') {tmp = 0;}

Не по теме:

опоздал)

0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
22.12.2012, 13:30 38
Цитата Сообщение от diagon Посмотреть сообщение
И вообще, зачем вы пишите все эти велосипеды?

Не по теме:

Из велосипедов я плюсанул бы за свою реализацию STL. Полезнее будет.

0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
22.12.2012, 13:51 39
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int myAtoi( std::string &str ) {
   bool sign = str[ 0 ] == '-';
   int n = 0;
   
   for( int i = sign ; i < str.size(); i++ ) {
      if( str[ i ] > '9' || str[ i ] < '0' )
         return 0;
      else
         n = n * 10 + ( str[ i ] - '0' );
   }
   
   if ( sign )
      return -n;
   
   return n;
}
Работает немного быстрее, чем atoi при O2 оптимизации в gcc.
1
14 / 14 / 1
Регистрация: 20.04.2010
Сообщений: 102
22.12.2012, 16:04 40
Цитата Сообщение от ValeryS
ты когда нибудь дизасемблировал Debug версию?
зачем лезть в асм. все проверяется куда проще:
C++
1
2
3
string a="123456789";
    char* c = new char (a[1]);
    cout<<c<<endl;
cout выводит поток символов до тех пор, пока не встретит \0. результат:
2¤¤¤¤▌▌▌°
Для продолжения нажмите любую клавишу . . .
как видишь, никакого \0 в памяти после двойки нет, ничего там компилятор вокруг двойки не занулял.
cout вывел мусор пока случайно не наткнулся на пустой байт.
думаю, на этом спор исчерпан.
Цитата Сообщение от ValeryS Посмотреть сообщение
как же по твоему отлавливать выход за пределы памяти
это делается не "занулением". new резервирует необходимое кол-во байт в незанятой памяти. компилятор это число запоминает и при попытке изменить значение ячейки ОП вне выделенного числа байт выдает ошибку. ничего за ее пределами он не "зануляет". это неэффективный расход памяти и опасно в конце концов. можно попасть не в свою память и что-нибудь важное "занулить".

Цитата Сообщение от ValeryS
а самый главный аргумент
atoi принимает строку
у ТС работает эта конструкция

C++
1
2
char* ch = new char(a[i]);
tmp = atoi(ch);
значит после памяти есть 0 и ch волшебным образом превращается в строку
она работает не потому что ch терминирован '\0', а потому что:
1. atoi игнорирует символы, не являющиеся числом. грубо говоря, в данной ситуации, он не обращает внимания на весь тот мусор, что лежит после 1 ого числового символа.
2. сканирует память до первого встретившегося \0. а он рано или поздно там встретиться. только вот сколько ему придется прочитать для этого байт - черт его знает. вот чтобы не пришлось читать лишнюю память, в спецификации и требуется \0 в конце.

Добавлено через 4 минуты
Цитата Сообщение от ValeryS
а если статическую строку дам?
статическая char строка терминуется \0 всегда. это стандарт языка. и лежит она в программном стеке, а не куче, где работает new.
0
22.12.2012, 16:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.12.2012, 16:04
Помогаю со студенческими работами здесь

Метод int MmPp(string str) для перевода строковой даты в число
Написать метод int MmPp(string str) {} Параметром является дата в виде &quot;21.mai&quot; (число, точка,...

Создайте класс Animal. Добавьте поля string Name, string Kind, string Areal, int Population
Здравствуйте! По C# есть задачка, с которой я так и не разобрался :( Задача: Создайте...

Создайте класс Animal. Добавьте поля string Name, string Kind, string Areal, int Population
Создайте класс Animal. Добавьте поля string Name, string Kind, string Areal, int Population....

Функция isspace и тип string: Не существует подходящей функции преобразования из "std::string" в "int"
Добрый день! Я только начинаю изучать язык c++ по книге &quot;Язык программирования С++. Базовый курс...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru