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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> оптимизировать код 
V
    Опции темы
ИванМ
Дата 15.4.2010, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Есть такой код. На входе число в формате xxxEyyy, на выходе xxx000..... Как его можно оптимизировать?
Код

string replace_e(string str)
{
    for(size_t i=0;i<str.length();i++)
    {
        if(str[i]=='e' || str[i]=='E')
        {
            stringstream s(str.substr(i+1));
            int n;
            s>>n;
            str.reserve(i+n);
            str.resize(i);
            s.clear();
            s.str("");
            s.fill('0');
            s.width(n);
            s<<"0";
            str.append(s.str());
            break;
        }
    }
    return str;
}



Это сообщение отредактировал(а) ИванМ - 15.4.2010, 23:54
PM MAIL   Вверх
djamshud
Дата 16.4.2010, 00:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


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

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



Число или все же строка? Или в коде строка только потому, что не можете с числом?


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
ИванМ
Дата 16.4.2010, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



djamshud, строка. Число нельзя потому что может быть любая размерность.
PM MAIL   Вверх
djamshud
Дата 16.4.2010, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


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

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



Код

char str[]={"1234E1265"};
char *pos=strpbrk(str,"eE");
if(pos!=0)
memset(pos,'0',strlen(str)-(pos-str));
printf("%s\n",str);


Вроде бы std::string позволяет работать напрямую с char*-данными. Тогда еще и strlen заменится на оптимальный str.length().


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
jonie
Дата 16.4.2010, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



не, ну если просто заменять то зачем парсить в int n что-то? банальный алгоритм какой-то такой:
Код

int pos=s.find_first_of('E');
string result = s.substr(0, pos);
result.append(s.size() - pos, '0'); //используй string& append ( size_t n, char c );  Appends a string formed by the repetition n times of character c.


UPD:
кстати:
Код

string& replace ( size_t pos1, size_t n1, size_t n2, char c );
string& replace ( iterator i1, iterator i2, size_t n2, char c );
    The section is replaced by a repetition of character c, n2 times.
заюзать стоит

Это сообщение отредактировал(а) jonie - 16.4.2010, 00:25


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
ИванМ
Дата 16.4.2010, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



djamshud, а нельзя C++ средствами? Не люблю я Си.
PM MAIL   Вверх
jonie
Дата 16.4.2010, 00:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



djamshud, не факт что можно делать memcpy в возращенный указатель, т.е. надо почитать, не возращает ли он константный указатель, а-то малоли как там внутри stl сделано...(возможно в некоторых реализациях вам будут давать например копию буфера, надо читать)


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
djamshud
Дата 16.4.2010, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


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

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



ИванМ, а я не умею stl. Но тот пример можно пропатчить на предмет std::string и он будет наверное крайне оптимальным.

Добавлено через 1 минуту и 19 секунд
jonie, если в std::string есть способ получить возможность работы напряму с внутренним буфером, то проблем не будет, т.к. изменения его размеров не происходит.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
jonie
Дата 16.4.2010, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



djamshud, прочти еще разок что я написал, в частности про теневую копию, а еще бывает copy-on-write и вы можете своей записью по указателю заколбасить заодно и ссылаемые строки... в общем ябы почитал что можно, а что низя ...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
djamshud
Дата 16.4.2010, 00:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


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

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



jonie, я внимательно читал, не сыпьте терминами. А сейчас прочитал описание этой строки, там предусмотрен доступ только для чтения (char const*). С ним работать опасно.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
mes
Дата 16.4.2010, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



решение в лоб, чтоб долго не думать :
Код

std::string replace_e (const std::string& str)
{  
    std::string s;
    s.reserve (str.size()-1);

    std::string::const_iterator it =  str.begin ();
    std::string::const_iterator end = str.end ();

    for (; it != end && (*it !='e' && *it != 'E'); ++it) 
      s.push_back (*it);

    for (++it; it != end; ++it ) 
      s.push_back('0');
   
    return s;
}



--------------------
PM MAIL WWW   Вверх
ИванМ
Дата 16.4.2010, 00:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



jonie
Цитата(jonie @  16.4.2010,  00:21 Найти цитируемый пост)
не, ну если просто заменять то зачем парсить в int n что-то? банальный алгоритм какой-то такой:

Не рабочий ваш код.
И если не парсить в int, то как мы узнаем количество символов? По любому надо переводить из string в int (а лучше конечно в size_t для моего случая).
string::replace только заменяет уже имеющиеся данные, которых у меня нет.
Вот с append(size_t, char) можно сократить код.
find_first_of тоже нельзя использовать, потому что может быть как 'e', так и 'E'.

djamshud, на сколько я знаю, нельзя работать в string с внутренним буфером.


mes
Цитата(mes @  16.4.2010,  00:43 Найти цитируемый пост)
    
for (++it; it != end; ++it ) 
      s.push_back('0');

Это очень медленно будет работать.
И, кстати, ваш код тоже не рабочий.

Пока так сделал:
Код

string replace_e(string str)
{
    for(size_t i=0;i<str.length();i++)
    {
        if(str[i]=='e' || str[i]=='E')
        {
            stringstream s(str.substr(i+1));
            int n;
            s>>n;
            str.reserve(i+n);
            str.resize(i);
            str.append(n, '0');
            break;
        }
    }
    return str;
}


Может я как то не так задачу описал.
Например, если строка=1e4, то должно быть на выходе: 10000.


Это сообщение отредактировал(а) ИванМ - 16.4.2010, 00:49
PM MAIL   Вверх
jonie
Дата 16.4.2010, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



djamshud, эт не термины - эт реальная жизнь. 
Для тех кто не вкурсе что такое copy-on-write это методика, когда например вы делаете копию строки, но реально буфер остается тот же самый, а вы по сути получаете пустышку, с буфером указывающим на буфер другой строки + для каждой ссылаемой сущьности проставляется признак "есть ссылка". Когда вы начинаете что-то менять в строке, тог проверяется этот признак, и, если он установлен, то производится создание нового буфера, копирование в него старого и изменение уже его (нового). Типа "копирование при записи". Эффективно экономит память, добавляет сложности при программировании, сложности отладки при перезаписи чужих данных, зачастую скорость падает...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
mes
Дата 16.4.2010, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(ИванМ @  15.4.2010,  23:46 Найти цитируемый пост)
Это очень медленно будет работать.

подправляю :
Код

std::string replace_e (const std::string& str)
{  
    std::string s;
    s.reserve (str.size()-1);

    std::string::const_iterator it =  str.begin ();
    std::string::const_iterator end = str.end ();

    for (; it != end && (*it !='e' && *it != 'E'); ++it) 
      s.push_back (*it);

    s.resize (str.size()-1,'0');
 
    return s;
}

smile


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


Эксперт
****


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

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



ИванМ, у меня не код, а псевдокод.
Цитата


string::replace только заменяет уже имеющиеся данные, которых у меня нет.
в исходной строке есть.
Цитата


find_first_of тоже нельзя использовать, потому что может быть как 'e', так и 'E'.
в исходном задании таких условий не было. кроме того,  find_first_of работает так:
Цитата

Searches the string for any of the characters that are part of either str, s or c, and returns the position of the first occurrence in the string.
туда можно прередать "eE".

Цитата


И если не парсить в int, то как мы узнаем количество символов? По любому надо переводить из string в int (а лучше конечно в size_t для моего случая).
эт я слабо понял. из задания нужно заменить все начиная (и включая) символ E до конца. Может и не так..


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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