On-line: tnsr2, гостей 2. Всего: 3 [подробнее..]
АвторСообщение
постоянный участник




Пост N: 1957
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 09.12.11 05:32. Заголовок: Подскажите алгоритм объединения сумм по одинаковому месяцу ?


Всем привет.
Имею двухмерный массив примерно такой:
 21,33 25.01.2011
 21,33 01.03.2011
 21,33 15.04.2011
 21,33 28.04.2011
 21,33 11.05.2011
 19,00 11.05.2011
 21,33 11.05.2011
 21,33 11.05.2011
 19,00 11.05.2011
 19,00 11.05.2011
 19,00 11.05.2011
 19,00 11.05.2011
 19,00 11.05.2011
 19,00 11.05.2011
 19,00 11.05.2011
 19,00 11.05.2011
 284,31 11.05.2011
 21,33 11.05.2011
 21,33 01.06.2011
 21,33 30.06.2011
 21,33 30.06.2011
 21,33 04.08.2011
 21,33 10.08.2011
 21,33 22.09.2011
 21,33 22.09.2011
 21,33 22.09.2011

Подскажите алгоритм как можно объеденить суммы по одинаковому месяцу.
Т.е. чтоб получился массив такого вида:
21,33 25.01.2011 - пропуск т.к. 1-месяц
21,33 01.03.2011 - пропуск т.к. 1-месяц
42,66 15.04.2011 - объединили
0,00 28.04.2011 - ....
540,63 11.05.2011 - объединили
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
0,00 11.05.2011
и т.д.

Заранее спасибо за ответ...



Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 8 [только новые]


постоянный участник


Пост N: 631
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 09.12.11 08:13. Заголовок: Как-то так... FUNCT..


Как-то так...

 
FUNCTION Something( aIn )

LOCAL aElem
LOCAL nMon := 0
LOCAL n1st
LOCAL aOut := {} // результат

FOR EACH aElem IN aIn
IF nMon <> Month( aElem[ 2 ] )
nMon := Month( aElem[ 2 ] )
AAdd( aOut, aElem )
n1st := Len( aOut )
ELSE
aOut[ n1st, 1 ] += aElem[ 1 ]
AAdd( aOut, { 0, aElem[ 2 ] } )
END // IF
NEXT

RETURN aOut


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2227
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 09.12.11 11:29. Заголовок: Перенес темку сюда...


Перенес темку сюда.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 1958
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 09.12.11 13:16. Заголовок: Получилось ! Только ..


Получилось ! Только не совсем правильно, в первом массиве "затирается" (просуммировался) первый элемент месяца.
1 - 25.01.11 , 21.33 -> 21.33
2 - 01.03.11 , 21.33 -> 21.33
3 - 15.04.11 , 42.66 -> 42.66
4 - 28.04.11 , 21.33 -> 0
5 - 11.05.11 , 540.63 -> 540.63
6 - 11.05.11 , 19.00 -> 0
7 - 11.05.11 , 21.33 -> 0
8 - 11.05.11 , 21.33 -> 0
9 - 11.05.11 , 19.00 -> 0
10 - 11.05.11 , 19.00 -> 0
11 - 11.05.11 , 19.00 -> 0
12 - 11.05.11 , 19.00 -> 0
13 - 11.05.11 , 19.00 -> 0
14 - 11.05.11 , 19.00 -> 0
15 - 11.05.11 , 19.00 -> 0
16 - 11.05.11 , 19.00 -> 0
17 - 11.05.11 , 284.31 -> 0
18 - 11.05.11 , 21.33 -> 0
19 - 01.06.11 , 63.99 -> 63.99
20 - 30.06.11 , 21.33 -> 0
21 - 30.06.11 , 21.33 -> 0
22 - 04.08.11 , 42.66 -> 42.66
23 - 10.08.11 , 21.33 -> 0
24 - 22.09.11 , 63.99 -> 63.99
25 - 22.09.11 , 21.33 -> 0
26 - 22.09.11 , 21.33 -> 0

Вот код:
Скрытый текст



Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 632
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 09.12.11 14:29. Заголовок: Andrey пишет: в пер..


Andrey пишет:

 цитата:
в первом массиве "затирается" (просуммировался) первый элемент месяца


Замени строку AAdd( aOut, aElem ) на AAdd( aOut, AClone( aElem ) )

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 1960
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 09.12.11 14:43. Заголовок: Спасибо БОЛЬШОЕ PSP ..


Спасибо БОЛЬШОЕ PSP !!!
А то после недельной работы по ночам голова совсем "не варит"...

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2201
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 09.12.11 19:10. Заголовок: Маленький совет. Нас..


Маленький совет. Насколько я понимаю, исходный массив получен в результате выборки из БД. Результирующий массив можно получить непосредственно, не формируя промежуточный. Примерно так:

aRes := {}
seek ...
while ...
AADDQ(aRes, Date, Summa)
skip
enddo

...
func AADDQ(aRes, xKey, nSum)
...
retu nil

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2207
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 17.12.11 12:37. Заголовок: Перенес функцию, фор..


Перенес функцию, формирующую результирующий массив, на C-уровень

http://zalil.ru/32298640

Пример использования:

Local aRes := {}
dbEval({|| AADDU(aRes, Date, Summa)})

2-й параметр - ключ для поиска в массиве, 3-й и так далее - числовые параметры для суммирования
Синтаксис вызова функции:
AADDU(<aArray>, <xKey>, <nSum1>, [nSum2], ...)

Функция выполняет поиск ключа в массиве методом половинного деления, и работает очень быстро.
Результирующий массив получается вида:
{{xKey1, nSum1, ...}, {xKey2, nSum2, ...}, ...}
Результирующий массив сразу отсортирован

В модуле также имеется функция AADDS() с аналогичными параметрами. Ее отличие от AADDU в том,
что входной поток для нее предполагается отсортированным, и ключ сравнивается только с последним
элементом массива. Но, поскольку метод половинного деления у меня реализован не классическим
способом, а несколько модифицированным: сначала сравнение выполняется на границы массива, первый
и последний элемент, разница в производительности между AADDU и AADDS незначительна.

Вместо поиска в массиве методом половинного деления, конечно, можно с тем же результатом
использовать тип данных хэш. Но я уже привык к своему способу, да и, как я уже написал, поиск
у меня немного отличается.

Тесты показывают, что перенос этого кода на C-уровень дает увеличение производительности примерно
в полтора раза. Это при том, что источник данных один и то же. Я сравнивал с функцией, которая
в качестве параметра получает подмассив: AADDQ(aRes, {xKey, nSum})
Ну а в сравнении с алгоритмом, используюшим обычный линейный поиск, производительность возрастает
раза в 3.

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


Спасибо: 1 
ПрофильЦитата Ответить
постоянный участник




Пост N: 1975
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 17.12.11 13:26. Заголовок: Pasha пишет: Тесты ..


Pasha пишет:

 цитата:
Тесты показывают, что перенос этого кода на C-уровень дает увеличение производительности примерно
в полтора раза. Это при том, что источник данных один и то же. Я сравнивал с функцией, которая
в качестве параметра получает подмассив: AADDQ(aRes, {xKey, nSum})
Ну а в сравнении с алгоритмом, используюшим обычный линейный поиск, производительность возрастает
раза в 3.



Ну что сказать - видно руку профессионала !
Спасибо БОЛЬШОЕ !!!

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 198
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет