Программа кодирования и декодирования ширины элементов на языке программирования С
В каждом подмножестве со структурой (n,k) значениям символа присваивают комбинации размеров элементов (различной ширины). Подпрограмма кодирования getRSSwidths на языке программирования С вычисляет размер (ширину) элементов для заданного значения подмножества. Подпрограмма декодирования getRSSvalue на языке программирования С вычисляет подмножество значений при заданных размерах элементов. Последовательные значения присваивают размерам поднабора элементов в установленном порядке.
Примечание - В программе на языке С использованы первоначальные идентификаторы, включающие в себя аббревиатуру "RSS". В программу на языке С не были внесены изменения, для того чтобы избежать внесения технических изменений в доступное к открытому доступу программное обеспечение.
Последовательность размеров элементов начинают с присвоения элементам с наименьшими номерами в поднаборах размера, равного одному модулю, или наименьшего размера, подходящего для данного поднабора (в соответствии с первой комбинацией под номером 0, всем ее элементам, кроме последнего, должен быть присвоен размер, равный одному модулю, если при этом для последнего элемента не будет превышено ограничение максимального размера элемента). Последующие значения присваивают следующей действительной комбинации, которая обеспечивает наименьшие размеры (самые узкие) из возможных для элементов с младшими номерами. Например, поднабор из 6 модулей содержит значения с номерами от 0 до 9 и соответствующие комбинации размеров элементов:
Значение | Комбинация размеров (ширина) элементов |
0 | 1 1 1 3 |
1 | 1 1 2 2 |
2 | 1 1 3 1 |
3 | 1 2 1 2 |
4 | 1 2 2 1 |
5 | 1 3 1 1 |
6 | 2 1 1 2 |
7 | 2 1 2 1 |
8 | 2 2 1 1 |
9 | 3 1 1 1 |
Комбинации с элементами, ширина которых превышает максимально допустимую (переменная maxWidth), пропускают. Кроме того, исключают шаблоны, в которых отсутствуют элементы шириной один модуль (переменная noNarrow = 0).
/*********************************************************************************** | ||||||||||||||
* getRSSwidths | ||||||||||||||
* подпрограмма генерации размеров (ширины) элементов GS1 DataBar для заданного значения. | ||||||||||||||
* | ||||||||||||||
* Calling arguments (аргументы вызова): | ||||||||||||||
* val = задаваемое значение | ||||||||||||||
* n = число модулей | ||||||||||||||
* elements = число пар элементов в наборе (для GS1 DataBar Всенаправленный, GS1 DataBar Усеченный, GS1 DataBar Двустрочный, GS1 DataBar Двустрочный Всенаправленный и GS1 DataBar Расширенный = 4; GS1 DataBar Ограниченный = 7) | ||||||||||||||
* maxWidth = максимальная ширина элемента в модулях | ||||||||||||||
* noNarrow = 0 пропуск шаблонов, не имеющих элементов шириной один модуль | ||||||||||||||
* | ||||||||||||||
* Return (возвращаемое значение): | ||||||||||||||
* static int widths[] = размеры (ширина) элементов | ||||||||||||||
/***********************************************************************************/ | ||||||||||||||
void getRSSwidths(int val, int n, int elements, int maxWidth, int noNarrow) | ||||||||||||||
{ | ||||||||||||||
int bar; | ||||||||||||||
int elmWidth; | ||||||||||||||
int i; | ||||||||||||||
int mxwelement; | ||||||||||||||
int subVal, lessVal; | ||||||||||||||
int narrowMask = 0; | ||||||||||||||
for (bar = 0; bar < elements-1; bar++) | ||||||||||||||
{ | ||||||||||||||
for (elmWidth = 1, narrowMask |= (1<<bar); | ||||||||||||||
; | ||||||||||||||
elmWidth++, narrowMask &= ~(1<<bar)) | ||||||||||||||
{ | ||||||||||||||
/* получение всех комбинаций */ | ||||||||||||||
subVal = combins(n-elmWidth-1, elements-bar-2); | ||||||||||||||
/* исключение комбинаций с отсутствием элементов шириной один модуль */ | ||||||||||||||
if ((!noNarrow) && (narrowMask == 0) && | ||||||||||||||
(n-elmWidth-(elements-bar-1) >= elements-bar-1)) | ||||||||||||||
{ | ||||||||||||||
subVal -= combins(n-elmWidth-(elements-bar), elements-bar-2); | ||||||||||||||
} | ||||||||||||||
/* исключение комбинаций с размером (шириной) элемента более допустимой > maxVal */ | ||||||||||||||
if (elements-bar-1 > 1) | ||||||||||||||
{ | ||||||||||||||
lessVal = 0; | ||||||||||||||
for (mxwElement = n-elmWidth-(elements-bar-2); | ||||||||||||||
mxwElement > maxWidth; | ||||||||||||||
mxwElement--) | ||||||||||||||
{ | ||||||||||||||
lessVal += combins(n-elmWidth-mxwElement-1, elements-bar-3); | ||||||||||||||
} | ||||||||||||||
subVal -= lessVal * (elements-1-bar); | ||||||||||||||
} | ||||||||||||||
else if (n-elmWidth > maxWidth) | ||||||||||||||
{ | ||||||||||||||
subVal-; | ||||||||||||||
} | ||||||||||||||
val -= subVal; | ||||||||||||||
if (val < 0) break; | ||||||||||||||
} | ||||||||||||||
val += subVal; | ||||||||||||||
n -= elmWidth; | ||||||||||||||
widths[bar] = elmWidth; | ||||||||||||||
} | ||||||||||||||
widths[bar] = n; | ||||||||||||||
return; | ||||||||||||||
} | ||||||||||||||
/***************************************************************** | ||||||||||||||
* getRSSvalue | ||||||||||||||
* подпрограмма вычисления подмножества значений при заданных размерах (ширине) элементов. | ||||||||||||||
* | ||||||||||||||
* Calling arguments (аргументы вызова): | ||||||||||||||
* widths[] = заданные размеры (ширина) элементов | ||||||||||||||
* elements = число пар элементов в наборе (для GS1 DataBar Всенаправленный, GS1 DataBar усеченный, GS1 DataBar Двустрочный, GS1 DataBar Двустрочный Всенаправленный и GS1 DataBar Расширенный = 4; GS1 DataBar ограниченный = 7); | ||||||||||||||
* | ||||||||||||||
* maxWidth = максимальная ширина элемента в модулях | ||||||||||||||
* noNarrow = 0 пропуск шаблонов, не имеющих элементов шириной один модуль | ||||||||||||||
* | ||||||||||||||
* Return (возвращаемое значение): | ||||||||||||||
* Значения подмножества | ||||||||||||||
***************************************************************** | ||||||||||||||
int getRSSvalue (int widths[], int elements, int maxWidth, int noNarrow) | ||||||||||||||
{ | ||||||||||||||
int val = 0; | ||||||||||||||
int n; | ||||||||||||||
int bar; | ||||||||||||||
int elmWidth; | ||||||||||||||
int i; | ||||||||||||||
int mxwElement; | ||||||||||||||
int subVal, lessVal; | ||||||||||||||
int narrowMask = 0; | ||||||||||||||
for (n = i = 0; i < elements; i++) | ||||||||||||||
{ | ||||||||||||||
n += widths[i]; | ||||||||||||||
} | ||||||||||||||
for (bar = 0; bar < elements-1; bar++) | ||||||||||||||
{ | ||||||||||||||
for (elmWidth = 1, narrowMask |= (1<<bar); | ||||||||||||||
elmWidth < widths[bar]; | ||||||||||||||
elmWidth++, narrowMask &= ~(1"bar)) { | ||||||||||||||
/* получение всех комбинаций nk */ | ||||||||||||||
subVal = combins(n-elmWidth-1, elements-bar-2); | ||||||||||||||
/* исключение комбинаций с отсутствующими узкими элементами */ | ||||||||||||||
if ((!noNarrow) && (narrowMask == 0) && | ||||||||||||||
(n-elmWidth-(elements-bar-1 )>= elements-bar-1)) | ||||||||||||||
{ | ||||||||||||||
subVal -= combins(n-elmWidth-(elements-bar), elements-bar-2); | ||||||||||||||
} | ||||||||||||||
/* исключение комбинаций с шириной элемента более допустимой > maxVal */ | ||||||||||||||
if (elements-bar-1 > 1) | ||||||||||||||
{ | ||||||||||||||
lessVal = 0; | ||||||||||||||
for (mxwElement = n-elmWidth-(elements-bar-2); | ||||||||||||||
mxwElement > maxWidth; mxwElement--) | ||||||||||||||
{ | ||||||||||||||
lessVal += combins(n-elmWidth-mxwElement-1, elements-bar-3); | ||||||||||||||
} | ||||||||||||||
subVal -= lessVal * (elements-1-bar); | ||||||||||||||
} | ||||||||||||||
else if (n-elmWidth > maxWidth) | ||||||||||||||
{ | ||||||||||||||
subVal--; | ||||||||||||||
} | ||||||||||||||
val += subVal; | ||||||||||||||
} | ||||||||||||||
n -= elmWidth; | ||||||||||||||
} | ||||||||||||||
return (val); | ||||||||||||||
} | ||||||||||||||
/***************************************************************** | ||||||||||||||
* компоновка (n,r): возврат множества комбинаций r, выбираемых из n: | ||||||||||||||
* Комбинации = n! /((n-r)! * r!) | ||||||||||||||
*****************************************************************/ | ||||||||||||||
int combins(int n, int r) { | ||||||||||||||
int i, j; | ||||||||||||||
int maxDenom, minDenom; | ||||||||||||||
int val; | ||||||||||||||
if (n-r > r) { | ||||||||||||||
minDenom = | ||||||||||||||
r; maxDenom | ||||||||||||||
= n-r; | ||||||||||||||
} | ||||||||||||||
else | ||||||||||||||
{ | ||||||||||||||
minDenom = n-r; | ||||||||||||||
maxDenom = r; | ||||||||||||||
} | ||||||||||||||
val = 1; | ||||||||||||||
j = 1; | ||||||||||||||
for (i = n; i > maxDenom; i--) { | ||||||||||||||
val *= i; | ||||||||||||||
if (j <= minDenom) { | ||||||||||||||
val/=j; | ||||||||||||||
j++ | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
for (; j <= minDenom; j++) { | ||||||||||||||
val/=j; | ||||||||||||||
} | ||||||||||||||
return (val); | ||||||||||||||
} |