Найти все сочетания от 1 до n объектов из m объектов
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | * (Вопрос) Нужно найти все сочетания 1, 2, ..., n объектов из m объектов. * (Ответ) Автор: rlevesque@videotron.ca, 30.08.2001; Сайт, посвящённый SPSS: http://www.spsstools.net. * Заметка: Это достаточно сложный синтаксис, который, впрочем, очень прост в использовании. Макрос n раз создаёт новый файл синтаксиса, который записывает сочетания в текстовый файл. Затем этот файл читается в редактор данных SPSS и используется для создания полного списка сочетаний. * См. пример использования в конце. SET MPRINT=no. */////////////////////////////. DEFINE !combine (n=!TOKENS(1) /items=!CMDEND). /* Ищем все сочетания 1,2, ... n объектов из m объектов*/ /* 30 августа 2001 года, rlevesque@videotron.ca */ * Считаем количество переданных переменных. !LET !nb=!NULL !DO !cnt !IN (!items) !LET !nb=!CONCAT(!nb,!BLANK(1)) !DOEND !LET !m=!LENGTH(!nb) !DO !thisn=1 !TO !n NEW FILE. INPUT PROGRAM. LOOP i=1 TO !thisn. END CASE. END LOOP. END FILE. END INPUT PROGRAM. LIST. !LET !list=!NULL !DO !cnt=1 !TO !thisn !LET !list=!CONCAT(!list," ","j",!cnt) !DOEND COMPUTE n=!thisn. * Получим имена переменных для цикла LOOP в команде WRITE ниже *. STRING cntname cntbeg(A8). COMPUTE cntname=CONCAT('j',LTRIM(STRING(i,F8.0))). * Получим первый параметр для цикла LOOP в команде WRITE ниже *. DO IF i=1. COMPUTE cntbeg="1". ELSE. COMPUTE cntbeg=CONCAT('j',LTRIM(STRING(i-1,F8.0))," + 1"). END IF. * Получим второй параметр для цикла LOOP в команде WRITE ниже *. COMPUTE k=!m - !thisn + i. FORMATS i k n(F8.0). STRING quote(A1) strlist(A255). COMPUTE quote='"'. COMPUTE strlist=!QUOTE(!list). * Запишем файл синтаксиса, который затем будет писать все сочетания в текстовый файл list.txt*. WRITE OUTFILE "c:\\temp\\macro.sps" /"LOOP "cntname"="cntbeg" TO "k".". DO IF i=!thisn. + WRITE OUTFILE "c:\\temp\\macro.sps" /"WRITE OUTFILE "quote"c:\\temp\\list.txt"quote "/" strlist "." . + LOOP cnt=1 TO !thisn. + WRITE OUTFILE "c:\\temp\\macro.sps" /"END LOOP.". + END LOOP. + WRITE OUTFILE "c:\\temp\\macro.sps" /"EXECUTE.". END IF. EXECUTE. INCLUDE FILE="c:\\temp\\macro.sps". /* Конвертируем данные из файла list.txt в соответствующий .sav файл */. DATA LIST FILE='c:\\temp\\list.txt' LIST /!list. SAVE OUTFILE=!QUOTE(!CONCAT('c:\\temp\\list',!thisn,'.sav')). !DOEND /* Собираем все .sav-файлы в один */. GET FILE='c:\\temp\\list1.sav'. !DO !nb=2 !TO !n. ADD FILES FILE=* /FILE=!QUOTE(!CONCAT('c:\\temp\\list',!nb,'.sav.')). !DOEND /* Убираем дубликаты */. SORT CASES BY ALL. MATCH FILES FILE=* /BY=ALL /FIRST=first. SELECT IF first. SAVE OUTFILE='c:\\temp\\all combinations.sav'. /* Ищем имя последнего объекта */ !DO !var !IN (!items) !LET !lastone=!var !DOEND VECTOR vnames(!m A8). !LET !cnt=!BLANK(1) /* Создаём переменные, содержащие названия объектов */ !DO !var !IN (!items) COMPUTE vnames(!LEN(!cnt))=!QUOTE(!var). !LET !cnt=!CONCAT(!cnt,!BLANK(1)) !DOEND /* Создаём строку, содержащую список сочетаний */. STRING items(A255). VECTOR j=j1 TO !CONCAT('j',!n) /ind=vnames1 TO !CONCAT('vnames',!m). COMPUTE nvar=NVALID(j1 TO !CONCAT('j',!n)). LOOP cnt=1 TO nvar. COMPUTE items=CONCAT(RTRIM(items)," ",vnames(j(cnt))). END LOOP. EXECUTE. !ENDDEFINE. *////////////////////////////. *************************. * Примеры использования. *************************. SET MPRINT=yes. !combine n=5 items=educ jobcat jobtime prevexp minority. * Example 2. !combine n=3 items=a b c d e f g. |
Related pages
...