powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как найти сумму чисел.
13 сообщений из 13, страница 1 из 1
Как найти сумму чисел.
    #32981474
Серж-1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть таблица (N) с полем (num, n, 2 ) там энное число цыфр. Как мне найти те цыфры которые в сумме будут = 3333?
Тоесть они могут складывать из 2, 3 и n значений.
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981513
Rustam Mukumov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если таблица фоксовская, то пробелм меньше.
Пишем функцию
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
function SumDigitsInNumber(tnNumber)
    Local lnSum
    lnSum =  0 
    do while tnNumber<> 0 
         lnSum =lnSum + tnNumber% 10 
         tnNumber = floor(tnNumber/ 10 )
     enddo
endfunc
Затем
Код: plaintext
select SumDigitsInNumber(num) from N
Если не фоксовская то можно сделать с излишними вычислениями
Код: plaintext
select num% 10 +floor(num/ 10 )% 10 +floor(num/ 100 )% 10 +...+floor(num/ 10 ... 0 )% 10 + from N
Блок floor(num/10...0) нужно повторить столько раз, сколько возможное максимальное кол-во цифр
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981521
Rustam Mukumov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В процедуре SumDigitsInNumber(tnNumber) забыл строку return lnSum
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981563
leaf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нуно найти один набор или все наборы ?
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981576
Серж-1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нето. Надо чтобы например 1, 20, 21, 45, 100, 127. в сумме были равны 3333.
А тут чото нето.
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981591
Серж-1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
надо найти 1-н вариант
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981605
leaf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы гарантируете чтонабор там есть???
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981613
Серж-1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да 101%
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981619
Серж-1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тоесть, приблизительно +-1,2. не более.
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981664
Фотография ГенГрум
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Серж-1Тоесть, приблизительно +-1,2. не более.


Уточни вопрос
- тебе нуно штоб по одному полю выбрать весе значения 3333+-1,2
тогда select ...
- первое значение тогда locate for ...
- при наличии индекса seek ...
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32981670
leaf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
рекурсия бы упростила задачу но кажеться в фоксе нет рекурсии
не охота перебор программировать в конце рабочего дня
а так в принципе более менее ясно выбрате то что пролазиет в курсор взять самое большое и повторить при неудаче вычеркнуть это число взять самое большое из оставшихся и т.д.
а вообще зачем тебе всё это нужно
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32982401
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi Серж-1!

Блин, ну ты конечно задал вопрос. Сам то понимаешь с первого раза свою постановку %)

Попробуем так:

Дана таблица test (nID I, num N(10,2)) содержащая кучу записей с различными значениями поля num (nID это последовательные "номера записей").
Требуется выбрать из этой таблицы некоторое множество записей, так чтобы в нём сумма полей num составляла 3333+/-2.

Теперь можно и решение предлагать :)

P.S. начать стоит с того, что:
1) В общем случае задача может:
а) Не иметь решения (например все num равны 1000 и "наилучшее" приближение это сумма=3000 что не попадает под условие)
б) Иметь одно или более решений.
2) Грубым перебором всех возможных комбинаций задача конечно решается, но за ОЧЕНЬ большое время (советую обратится к комбинаторике и посмотреть на факториал - ибо число всевозможных выборок из N записей это N! - уже для 100 записей это число со 157 знаками!) - т.е. явно никто не доживёт до завершения расчёта.
3) Алгоритмов "интеллектуальной" выборки может быть создано МНОГО - все они будут иметь разную эффективность, и НЕ все будут способны найти правильное решение (например предложенный leaf алгоритм на первый взгляд гарантирует нахождения верного решения, но весьма и весьма неэффективным способом).
4) Если задача будет "слегка изменена" и нужно будет не "из всего массива насобирать на 3333", а скажем "разбить массив на подмножества, в каждом из которых сумма элементов задана отдельно" - тогда это будет СОВСЕМ другая задача, и совсем иными методами решаемая.

P.P.S. Что-то мне это напоминает задачу "раскидать N платёжных документов по M договорам" - там обычно существует одно КАРДИНАЛЬНОЕ упрощение - одну "сумму платежа" можно распределить на 2 (а иногда и больше) "договора" - т.е. всё решается банально.

Posted via ActualForum NNTP Server 1.1
...
Рейтинг: 0 / 0
Как найти сумму чисел.
    #32982683
Фотография neznajka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Серж-1:
Действительно, похоже на раскидывание платежных сумм по документам.
Но если рассматривать математически именно предоставленную вами таблицу,
то можно попытаться что-то порешать. А именно:
Для приведенной вами таблицы (143 записи), 126 из которых
не превышают заданного предела суммы, максимально допустимое
количество слагаемых для достижения заданной суммы равно 59 (m.kol_max см.ниже)
(очевидно, что максимум количества слагаемых может достигаться
только при сложении наименьших из имеющихся значений NUM).
Минимальное количество слагаемых - 2, раз в таблице нет значения NUM,
которое "в одиночку" удовлетворяло бы заданному значению суммы.
Исходя из таких граничных условий уже можно кое-что подсчитать.
Максимальное количество возможных вариантов - действительно велико:
Сочетаний_из_126_по_59 + Сочетаний_из_126_по_58 + ... Сочетаний_из_126_по_2 =
~5,33Е+39. Вычислений не привожу - простая комбинаторика, к делу не относится.
Можно сказать только, что перебрать такое количество вариантов -
никаких компутеров не хватит. А если учесть, что для анализа такого объема информации
его сначала нужно где-то разместить - на это понадобится более 4,96Е+30 Гб!
К сожалению, у меня такого ВИНТА нету под рукой, поэтому попытался решить
вашу задачку путем сохранения промежуточной суммы как начальной для каждой
последующей итерации. Не уверен, что получаемый результат охватывает ВСЕ
возможные варианты, но полученных вариантов - вполне достаточно. Судите сами:

SET DECIMALS TO 2
&& Таблица для накопления вычисляемых сумм и их слагаемых
CREATE TABLE sumy (sym n (7,2),sostav m(4))
&& Допустимая погрешность. Я задал такую.
m.pogr=0.06
&& Выборка тех NUM, которые не превышают заданного предела
&& и их сортировка для упорядоченного перебора вариантов сложения
SELECT num FROM n WHERE num<3333+m.pogr ORDER BY 1 INTO ARRAY nn
m.sums=0 && Переменная текущей вычисленной суммы
i=1 && Переменная индекса массива
&& Очевидно, что для вычисления МАКСИМАЛЬНО ВОЗМОЖНОГО количества слагаемых
&& необходимо суммировать их, начиная с наименьших (i=1, ведь данные отсортированы)
DO While m.sums<3333+m.pogr
m.sums=m.sums+nn
i=i+1
ENDDO
m.kol_max=i && Максимальное количество слагаемых
&& Перебор значений массива удобнее вести "снизу" - с наибольшего элемента,
&& добавляя к нему значения, начиная с наименьших элементов,
&& тогда "точка встречи"
и будет окончанием перебора значений
FOR t=ALEN(nn) TO m.kol_max STEP -1 && Цикл для каждого АНАЛИЗИРУЕМОГО элемента массива
m.sums=nn[t] && При переборе "снизу" - это начальное значение суммы (для каждого очередного элемента массива)
i=1
&& Цикл для определения максимально возможного количества слагаемых
&& для данного элемента массива, чтобы сумма не превышала требуемую
DO WHILE m.sums<3333+m.pogr
m.sums=m.sums+nn
i=i+1
ENDDO
m.kol_iter=i-1 && Вычисленное в цикле значение максимального количества слагаемых
m.sumprom=0 && Вспомогательная переменная для запоминания результатов предыдущих вариантов суммирования
FOR j=1 TO m.kol_iter && Цикл перебора нарастающего количества слагаемых для данного очередного [t] элемента массива m.sumprom=IIF(j=1,nn[t],m.sumprom+nn[j-1]) && Запоминание предыдущей суммы элементов
&& m.strn - переменная для запоминания в символьном виде выражения суммы перебранных элементов
m.strn=IIF(j=1,ALLTRIM(STR(nn[t],7,2)),m.strn+'+'+ALLTRIM(STR(nn[j-1],7,2)))
m.sums=m.sumprom && Начальное значение суммы после добавления очередного слагаемого
i=j && Начальное значение очередного НОВОГО добавляемого элемента-слагаемого (ведь выше - добавляся [j-1]-ый элемент)
&& Цикл перебора сочетания новых "далее расположенных" элементов с предыдущим набором элементов, сумма которых сохранена в m.sumprom
DO WHILE m.sums<3333+m.pogr
m.sums=m.sumprom+nn
IF BETWEEN(m.sums,3333-m.pogr,3333+m.pogr) && Если сумма "попадает" в допустимый диапазон - запись данного варианта сложения в файл sumy.dbf
m.strn=m.strn+'+'+ALLTRIM(STR(nn,7,2))
INSERT INTO sumy (sym,sostav) VALUES (m.sums,m.strn)
ENDIF
i=i+1
ENDDO
&& Досрочное завершение перебора, если сумма уже превышает домустимый предел
IF BETWEEN(m.sums,3333-m.pogr,3333+m.pogr)
LOOP
ENDIF
ENDFOR
ENDFOR
&& Выборка допустимых сумм и их составляющих(memo)
SELECT * from sumy WHERE ABS(EVALUATE(CHRTRAN(ALLTRIM(sostav),',','.'))-3333)<m.pogr ORDER BY sym

К сожалению, в выборку попадают и "зеркальные"(симметричные) наборы слагаемых,
видимо, не совсем верно выбран критерий выхода из цикла или "точка встречи"
для четного количества элементов массива.
Но, думаю, такое дублирование результатов не столь важно в данном случае.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как найти сумму чисел.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]