std::accumulate
От: Draqon  
Дата: 30.01.04 08:07
Оценка:
Граждане, объясните чайнику!
Есть string вида [A-Z]+, т.е. состоит из одной или более латинских больших букв.
Считаем такую штуку:


unsigned int result;
string s; // это наша строка
....
for (string::iterator i=s.begin(); i!=s.end(); ++i)
        result = result*26 + (*i) - 'A' + 1;



Нутром чую, что можно это с помощью std::accumulate сделать, а вот как?...

P.S. и без boost.
Re: std::accumulate
От: What Беларусь  
Дата: 30.01.04 08:29
Оценка:
Здравствуйте, Draqon, Вы писали:

D>Есть string вида [A-Z]+, т.е. состоит из одной или более латинских больших букв.

D>Считаем такую штуку:

D>
D>unsigned int result;
D>string s; // это наша строка
D>....
D>for (string::iterator i=s.begin(); i!=s.end(); ++i)
D>        result = result*26 + (*i) - 'A' + 1;
D>


NB:
1. result может быть меньше 0, если строка не имеет вид [A-Z]+, поэтому я бы заменил его тип на int
2. Чем result инициализируется?


D>Нутром чую, что можно это с помощью std::accumulate сделать, а вот как?...


struct CAccumFunc
{
    inline int operator() (int Res, int Cur)
    {
        return Res*26 + Cur - 'A' + 1;
    }
};

int InitValue = 0; // Начальное значение
int Res = std::accumulate(s.begin(), s.end(), InitValue, CAccumFunc());
Re: std::accumulate
От: WolfHound  
Дата: 30.01.04 08:33
Оценка:
Здравствуйте, Draqon, Вы писали:

D>Нутром чую, что можно это с помощью std::accumulate сделать, а вот как?...

struct op
{
    int operator()(int res, int val)
    {
        return res*26+val-'A'+1;
    }
};
int main()
{
    std::string str="AZ";
    int res=std::accumulate(str.begin(), str.end(), 0, op());
    return 0;

D>P.S. и без boost.
И зря
boost::lambda
    int res2=std::accumulate(str.begin(), str.end(), 0, _1*26+_2-'A'+1);
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: std::accumulate
От: Vamp Россия  
Дата: 30.01.04 08:35
Оценка:
unsigned int calc(unsigned int r, char c) {
   return r*26+c-'A'+1;
} 

r=std::accumulate(s.begin(), s.end(), 0, calc);
Да здравствует мыло душистое и веревка пушистая.
Re[2]: std::accumulate
От: WolfHound  
Дата: 30.01.04 08:37
Оценка:
Здравствуйте, What, Вы писали:

W>1. result может быть меньше 0, если строка не имеет вид [A-Z]+, поэтому я бы заменил его тип на int

Если строка не имеет такой вид то эта формула вобще говоря становится полным бредом.
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: std::accumulate
От: ArtDenis Россия  
Дата: 30.01.04 08:41
Оценка:
Здравствуйте, Draqon, Вы писали:

D>...

D>Нутром чую, что можно это с помощью std::accumulate сделать, а вот как?...

А тебе оно надо?

Если это расчёт hash-функции, то твой вариант — однозначно быстрее, а соответственно и лучше.
... << RSDN@Home 1.1.2 stable >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[2]: std::accumulate
От: Vamp Россия  
Дата: 30.01.04 08:44
Оценка:
AD>Если это расчёт hash-функции, то твой вариант — однозначно быстрее, а соответственно и лучше.
Really? А почему вы считаете, что многократный вызов в цикле функции end() однозначно быстрее, чем однократное вычисление при вызове алгоритма?
Apart from that error, вы проводили вычисление, что быстрее — accumulate или собственный цикл? И ли просто так считате?
Apart from that, и наконец, почему вы считаете, что быстрее — это синоним слова лучше?
Да здравствует мыло душистое и веревка пушистая.
Re[3]: std::accumulate
От: ArtDenis Россия  
Дата: 30.01.04 08:50
Оценка: 2 (1)
Здравствуйте, Vamp, Вы писали:

AD>>Если это расчёт hash-функции, то твой вариант — однозначно быстрее, а соответственно и лучше.

V>Really? А почему вы считаете, что многократный вызов в цикле функции end() однозначно быстрее, чем однократное вычисление при вызове алгоритма?
Согласен, просмотрел:
for (string::iterator i=s.begin(), end = s.end(); i != end; ++i)
        result = result*26 + (*i) - 'A' + 1;


V>Apart from that error, вы проводили вычисление, что быстрее — accumulate или собственный цикл? И ли просто так считате?

Считаю. Но если интересно, могу и проверить.

V>Apart from that, и наконец, почему вы считаете, что быстрее — это синоним слова лучше?

Постори начало моего ответа.
... << RSDN@Home 1.1.2 stable >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[4]: std::accumulate
От: WolfHound  
Дата: 30.01.04 08:59
Оценка: 2 (1)
Здравствуйте, ArtDenis, Вы писали:

AD>Считаю. Но если интересно, могу и проверить.

; 58   :     for (std::string::iterator i=str.begin(), end = str.end(); i != end; ++i)

    mov    edx, DWORD PTR _str$[esp+116]
    mov    esi, DWORD PTR _str$[esp+96]
    xor    eax, eax
    cmp    edx, 16                    ; 00000010H
    mov    DWORD PTR __$EHRec$[esp+100], 0
    mov    ecx, esi
    jae    $L109634
    lea    ecx, DWORD PTR _str$[esp+96]
    mov    edx, ecx
$L101998:
    mov    esi, DWORD PTR _str$[esp+112]
    add    edx, esi
    cmp    ecx, edx
    je    SHORT $L31587
$L102007:

; 59   :             res = res*26 + (*i) - 'A' + 1;

    movsx    esi, BYTE PTR [ecx]
    imul    eax, 26                    ; 0000001aH
    inc    ecx
    cmp    ecx, edx
    lea    eax, DWORD PTR [eax+esi-64]
    jne    SHORT $L102007
$L31587:

; 61   :     res=std::accumulate(str.begin(), str.end(), 0, op());

    mov    esi, DWORD PTR _str$[esp+116]
    cmp    esi, 16                    ; 00000010H
    mov    ecx, DWORD PTR _str$[esp+96]
    mov    eax, ecx
    jae    SHORT $L102157
    lea    eax, DWORD PTR _str$[esp+96]
$L102157:
    mov    edx, DWORD PTR _str$[esp+112]
    add    edx, eax
    cmp    esi, 16                    ; 00000010H
    jae    SHORT $L102185
    lea    ecx, DWORD PTR _str$[esp+96]
$L102185:
    xor    eax, eax
    cmp    ecx, edx
    je    SHORT $L102216
    npad    6
$L102219:
    movsx    esi, BYTE PTR [ecx]
    imul    eax, 26                    ; 0000001aH
    inc    ecx
    cmp    ecx, edx
    lea    eax, DWORD PTR [eax+esi-64]
    jne    SHORT $L102219
$L102216:
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: std::accumulate
От: Vamp Россия  
Дата: 30.01.04 09:05
Оценка:
Т.е. inline вполнился на ура.
Подозреваю, это VC7.1?
Да здравствует мыло душистое и веревка пушистая.
Re[5]: std::accumulate
От: ArtDenis Россия  
Дата: 30.01.04 09:07
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>...


Ладно, почти уговорили.

Но надо учитывать ещё и то, что не все компиляторы такие "правильные". Кстати, а как будет выглядеть код в случае использования boost::lambda ?
... << RSDN@Home 1.1.2 stable >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[6]: std::accumulate
От: WolfHound  
Дата: 30.01.04 09:19
Оценка: 2 (1)
Здравствуйте, ArtDenis, Вы писали:

AD>Но надо учитывать ещё и то, что не все компиляторы такие "правильные". Кстати, а как будет выглядеть код в случае использования boost::lambda ?

На одну команду больше
; 19   :     res=std::accumulate(str.begin(), str.end(), 0, _1*26+_2-'A'+1);

    lea    ecx, DWORD PTR $T61214[esp+92]
    push    ecx
    lea    ecx, DWORD PTR $T61952[esp+96]
    mov    DWORD PTR $T61214[esp+100], 26        ; 0000001aH
    mov    BYTE PTR $T61214[esp+108], 65        ; 00000041H
    mov    DWORD PTR $T61214[esp+112], 1
    call    ??0?$cons@V?$lambda_functor@U?$placeholder@$00@lambda@boost@@@lambda@boost@@U?$cons@$$CBHUnull_type@tuples@boost@@@tuples@3@@tuples@boost@@QAE@ABU012@@Z
    mov    esi, DWORD PTR _str$[esp+116]
    cmp    esi, 16                    ; 00000010H
    mov    ecx, DWORD PTR _str$[esp+96]
    mov    eax, ecx
    jae    SHORT $L61239
    lea    eax, DWORD PTR _str$[esp+96]
$L61239:
    mov    edx, DWORD PTR _str$[esp+112]
    add    edx, eax
    cmp    esi, 16                    ; 00000010H
    jae    SHORT $L61266
    lea    ecx, DWORD PTR _str$[esp+96]
$L61266:
    xor    eax, eax
    cmp    ecx, edx
    je    SHORT $L61940
    mov    esi, DWORD PTR $T61952[esp+96]
    npad    4
$L61943:
    mov    edi, esi
    imul    edi, eax
    movsx    eax, BYTE PTR [ecx]
    inc    ecx
    cmp    ecx, edx
    lea    eax, DWORD PTR [edi+eax-64]
    jne    SHORT $L61943
$L61940:

Однако если чуть-чуть изменить выражение
; 19   :     res=std::accumulate(str.begin(), str.end(), 0, _1*26+(_2-'A'+1));

    mov    esi, DWORD PTR _str$[esp+76]
    cmp    esi, 16                    ; 00000010H
    mov    ecx, DWORD PTR _str$[esp+56]
    mov    eax, ecx
    jae    SHORT $L58624
    lea    eax, DWORD PTR _str$[esp+56]
$L58624:
    mov    edx, DWORD PTR _str$[esp+72]
    add    edx, eax
    cmp    esi, 16                    ; 00000010H
    jae    SHORT $L58651
    lea    ecx, DWORD PTR _str$[esp+56]
$L58651:
    xor    eax, eax
    cmp    ecx, edx
    je    SHORT $L59222
$L59167:
    movsx    esi, BYTE PTR [ecx]
    imul    eax, 26                    ; 0000001aH
    inc    ecx
    cmp    ecx, edx
    lea    eax, DWORD PTR [eax+esi-64]
    jne    SHORT $L59167
$L59222:

Вобщем есть мелкомягким куда работать но всеравно
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: std::accumulate
От: WolfHound  
Дата: 30.01.04 09:19
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Т.е. inline вполнился на ура.

V>Подозреваю, это VC7.1?
Правильно подозреваешь.
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: std::accumulate
От: ArtDenis Россия  
Дата: 30.01.04 11:36
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>...


Эх, а я ожидал гораздо худшего . Снимаю шляпу перед теми, кто разрабатывал оптимизатор для VC.
... << RSDN@Home 1.1.2 stable >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[8]: std::accumulate
От: Draqon  
Дата: 30.01.04 11:52
Оценка:
Э, граждане, граждане!

Во-первых: спасибо за ответы.
Во-вторых: скорость не очень критична, хотя с замечанием об end() согласен на 100%.
В-третьих: с вынесеним формулы в функциональный объект (именованный либо лямбда) и так всё ясно. Вопрос в том, как (можно ли) с помощью СТАНДАРТНЫХ средств С++ & STL эту лямбду как-то сделать.

[off]Чувствую скоро с помощью STL получится С++-диалект ЛИСПа [/off]
Re[2]: std::accumulate
От: Андрей Галюзин Украина  
Дата: 31.01.04 12:53
Оценка:
V>
V> unsigned int calc(unsigned int r, char c) {
V>    return r*26+c-'A'+1;
V> }

r=std::accumulate(s.begin(), s.end(), 0, calc);
V>


Лучше все же функтором, как чуть выше WolfHound'а.
Потому как вероятность встраивания calc гораздо меньше, чем op::operator().

--
aga
Posted via RSDN NNTP Server 1.7 "Bedlam"
Re[9]: std::accumulate
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 31.01.04 16:39
Оценка:
Здравствуйте, Draqon, Вы писали:

D>Вопрос в том, как (можно ли) с помощью СТАНДАРТНЫХ средств С++ & STL эту лямбду как-то сделать.

Вопрос в том, что понимать под станлартными средствами.
Re[10]: std::accumulate
От: Андрей Галюзин Украина  
Дата: 31.01.04 16:51
Оценка:
D>>Вопрос в том, как (можно ли) с помощью СТАНДАРТНЫХ средств С++ & STL эту лямбду как-то
D>>сделать.
A> Вопрос в том, что понимать под станлартными средствами.

Дефакто или деюро?

--
aga
Posted via RSDN NNTP Server 1.7 "Bedlam"
Re[11]: std::accumulate
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 31.01.04 18:17
Оценка:
Здравствуйте, Андрей Галюзин, Вы писали:

D>>>Вопрос в том, как (можно ли) с помощью СТАНДАРТНЫХ средств С++ & STL эту лямбду как-то

D>>>сделать.
A>> Вопрос в том, что понимать под станлартными средствами.

АГ>Дефакто или деюро?


Вот в том-то и дело, что де-юре ламбда реализована вполне стандартными средствами; вопрос о том, что понимать под стандартными де-факто вещами остается открытым .
Подозреваю, для Wolfhound'а это вполне стандартные вещи.
Re[12]: std::accumulate
От: Андрей Галюзин Украина  
Дата: 02.02.04 12:59
Оценка:
A> Вот в том-то и дело, что де-юре ламбда реализована вполне стандартными средствами; вопрос о
A> том, что понимать под стандартными де-факто вещами остается открытым .

Вопрос, конечно, открытый, но кое-что можно узнать уже сейчас. Подробности не помню, за справками к Паше или Максиму.
Например, boost::function и boost::shared_ptr с высокой вероятностью войдут в стандарт.

A> Подозреваю, для Wolfhound'а это вполне стандартные вещи.


Впрочем, как и для многих других.

--
aga
Posted via RSDN NNTP Server 1.7 "Bedlam"
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.