powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / проблема с SEEK
10 сообщений из 10, страница 1 из 1
проблема с SEEK
    #33653533
100gram
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть БД с номером поля и 5 числами. 50000 записей.
Выбираю одну запись случайным образом и ищу по базе похожие, т.е. записи, содержащие 4,3,2 из 5 чисел этой записи. Здесь я что-то не допонимаю, как работает SEEK. Она не обрабатывает все записи, находит одну и успокаивается. А мне надо дальше искать :-) Циклы пробовал, тоже не получается. Что я делаю неправильно?



Код:
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.
scan 
IF (SEEK(game2(1)) AND SEEK(game2(2)) AND SEEK(game2(3)) AND SEEK(game2(4)))
 var1 = var1 +1
ENDIF 
IF SEEK(game2(2)) AND SEEK(game2(3)) AND SEEK(game2(4)) AND SEEK(game2(5))
 var1 = var1 +1
ENDIF 
IF SEEK(game2(3)) AND SEEK(game2(4)) AND SEEK(game2(5)) AND SEEK(game2(1))
 var1 = var1 +1
ENDIF 
IF SEEK(game2(4)) AND SEEK(game2(5)) AND SEEK(game2(1)) AND SEEK(game2(2))
 var1 = var1 +1
ENDIF 
IF SEEK(game2(1)) AND SEEK(game2(2)) AND SEEK(game2(3)) AND SEEK(game2(5))
 var1 = var1 +1
ENDIF 

IF SEEK(game2(1)) AND SEEK(game2(2)) AND SEEK(game2(3)) 
 var2 = var2 +1
ENDIF 
IF SEEK(game2(1)) AND SEEK(game2(3)) AND SEEK(game2(4)) 
 var2 = var2 +1
ENDIF 
IF SEEK(game2(1)) AND SEEK(game2(4)) AND SEEK(game2(5)) 
 var2 = var2 +1
ENDIF 
IF SEEK(game2(1)) AND SEEK(game2(2)) AND SEEK(game2(5)) 
 var2 = var2 +1
ENDIF 
IF SEEK(game2(1)) AND SEEK(game2(3)) AND SEEK(game2(5)) 
 var2 = var2 +1
ENDIF 
IF SEEK(game2(2)) AND SEEK(game2(3)) AND SEEK(game2(4)) 
 var2 = var2 +1
ENDIF 
IF SEEK(game2(2)) AND SEEK(game2(4)) AND SEEK(game2(5)) 
 var2 = var2 +1
ENDIF 
IF SEEK(game2(3)) AND SEEK(game2(4)) AND SEEK(game2(5)) 
 var2 = var2 +1
ENDIF 

IF SEEK(game2(1)) AND SEEK(game2(2))
 var3 = var3 +1
ENDIF 
IF SEEK(game2(1)) AND SEEK(game2(3))
 var3 = var3 +1
ENDIF 
IF SEEK(game2(1)) AND SEEK(game2(4))
 var3 = var3 +1
ENDIF 
IF SEEK(game2(1)) AND SEEK(game2(5))
 var3 = var3 +1
ENDIF 
IF SEEK(game2(2)) AND SEEK(game2(3))
 var3 = var3 +1
ENDIF 
IF SEEK(game2(2)) AND SEEK(game2(4))
 var3 = var3 +1
ENDIF 
IF SEEK(game2(2)) AND SEEK(game2(5))
 var3 = var3 +1
ENDIF 
IF SEEK(game2(3)) AND SEEK(game2(4))
 var3 = var3 +1
ENDIF 
IF SEEK(game2(3)) AND SEEK(game2(5))
 var3 = var3 +1
ENDIF 
IF SEEK(game2(4)) AND SEEK(game2(5))
 var3 = var3 +1
ENDIF 

SKIP
endscan
...
Рейтинг: 0 / 0
проблема с SEEK
    #33653680
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если так уж сильно в лом почитать HELP, то хоть сам поэкспериментировать мог бы как работает SEEK. Всего-то надо открыть BROWSE-окно, последовательно давать команды в командном окне и смотреть куда встанет указатель записи.

Выражение типа

SEEK(1) AND SEEK(2)

означает, что в таблице есть запись со значением индексного ключа 1 и со значением индексного ключа 2. Причем, вовсе не обязательно, что это одна запись. Ты сначала делаешь поиск по ключу 1, а потом НОВЫЙ поиск по ключу 2.

Опиши задачу более подробно. Хотя бы приведи структуру твоей таблицы. Что ищешь и что должно получиться в результате. Только не словами, а таблицами. Вот есть такие данные, надо найти вот эти данные.
...
Рейтинг: 0 / 0
проблема с SEEK
    #33653873
100gram
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
понятно, так я и думал.
Хелп я читал, но не понял. Спасибо за объяснение.

Задача более подробно:
есть таблица (50000 записей). Идентификатор поля (I AutoInc) и 5 полей со случайными числами от 1 до 25 (c). я посчитал, что character будет более удобным.

Каждая запись уникальна и отсортирована по возрастанию.

Я выбираю случайно одну запись. Затем ищу все записи, которые имеют любые 4 из 5 чисел той выбранной записи. Затем ищу 3 из 5, 2 из 5.

Это лотерея (имитация розыгрыша).
...
Рейтинг: 0 / 0
проблема с SEEK
    #33653952
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При такой структуре данных простого решения не получишь. Проблема в том, что непонятно что именно надо искать. Не в смысле постановки задачи (это-то ясно), а в смысле структуры данных.

Предположим, у тебя в одной записи есть 5 чисел, выстроенных в порядке возрастания: 2, 5, 7, 10, 20

Надо найти записи, у которых совпадают 4 из этих 5 чисел. Ты представляешь общее количество вариантов таких совпадений? ЧТО искать будем? Надо найти именно запись, а не числа. Причем заранее неизвестно в какой именно позиции искомые числа находятся.

Ну, предположим, ищем первые 4 числа. Это значит возможны такие варианты

X, 2, 5, 7, 10
2, X, 5, 7, 10
2, 5, X, 7, 10
2, 5, 7, X, 10
2, 5, 7, 10, X

Здесь вместо X - любое число. А теперь, по очереди выбрасывай числа из оригинальной последовательности. Т.е. всего имеем 25 вариантов того, чего надо искать. И это только на ОДНУ запись. А у тебя их 50000.

Тут надо действовать по другому. Примерно так:

Код: plaintext
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.
USE MyTab IN  0 
USE MyTab IN  0  AGAIN ALIAS TabDoubl

LOCAL lcCharString, lnI, laDouble( 4 )
SELECT MyTab
SCAN
	lcCharString = CHR(VAL(MyTab.F1))+;
			CHR(VAL(MyTab.F2))+;
			CHR(VAL(MyTab.F3))+;
			CHR(VAL(MyTab.F4))+;
			CHR(VAL(MyTab.F5)))
	laDouble =  0 
	FOR m.lnI= 4  TO  2  STEP - 1 
		SELECT TabDoubl
		LOCATE FOR LEN(ChrTran(CHR(VAL(TabDoubl.F1))+;
			CHR(VAL(TabDoubl.F2))+;
			CHR(VAL(TabDoubl.F3))+;
			CHR(VAL(TabDoubl.F4))+;
			CHR(VAL(TabDoubl.F5)), m.lcCharString,""))=( 5 -m.lnI) ;
			AND Recno("TabDouble")<>Recno("MyTab")
		DO WHILE FOUND("TabDouble")=.T.
			laDouble[m.lnI] = laDouble[m.lnI]+ 1 
			CONTINUE
		ENDDO
	ENDFOR
* Здесь имеем массив laDouble в котором в соответствующем элементе 
* записано количество встречающихся совпадений
* для ТЕКУЩЕЙ записи
* В  4  элементе - количество совпадений  4  символов
* В  3  элементе - количество совпадений  3  символов
* Во  2  элементе - количество совпадений  2  символов
ENDSCAN

Могу сразу сказать, что этот код будет работать ОЧЕНЬ медленно.

Идея проверки основана на работе функции ChrTran()

?ChrTran("ABCDE","ABCFG","")

В таком синтаксисе из первого выражения будут исключены все символы встречающиеся во втором. При этом, не важно где именно в выражении эти символы находились. Далее остается проверить длину полученного выражения. Если были исключены 4 символа, длина будет 1.

Чтобы представить число 25 как один символ я предполагаю, что 25 это ASCII-код символа и перевожу его в символ при помощи функции CHR(). Поскольку у тебя все данные записаны в символьном виде, то перевожу их в числа при помощи функции VAL().

То же самое в виде запроса

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT ;
	a.id, ;
	SUM(IIF(LEN(CharTran("a. ...", "b. ...",""))= 1 ,  1 ,  0 ) as Doubl4, ;
	SUM(IIF(LEN(CharTran("a. ...", "b. ...",""))= 2 ,  1 ,  0 ) as Doubl3, ;
	SUM(IIF(LEN(CharTran("a. ...", "b. ...",""))= 3 ,  1 ,  0 ) as Doubl2 ;
FROM MyTab a, MyTab b ;
WHERE a.id <> b.id ;
GROUP BY a.id

Здесь вместо многоточий во всех 3 выражениях надо писать одно и то же

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
ChrTran( ;
	CHR(VAL(a.F1))+;
	CHR(VAL(a.F2))+;
	CHR(VAL(a.F3))+;
	CHR(VAL(a.F4))+;
	CHR(VAL(a.F5)), ;
	CHR(VAL(b.F1))+;
	CHR(VAL(b.F2))+;
	CHR(VAL(b.F3))+;
	CHR(VAL(b.F4))+;
	CHR(VAL(b.F5)), ;
	"" ;
	)

Т.е. все тот же CharTran, где первое выражение составлено из полей первой копии таблицы, а второе - из полей второй копии таблицы
...
Рейтинг: 0 / 0
проблема с SEEK
    #33654441
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi Владимир!

Практически идентичное обсуждение (касающееся лотерейной игры) было
некоторое время назад на этом форуме - никакого приемлемого (по времени
работы) способа сделать это на фоксе найдено не было - я специально посылал
код на C# реализующий определённый вид поиска решения (не такой как
требуется сейчас :) но это не существенно).

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
проблема с SEEK
    #33654541
100gram
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мда, нетривиально. Спасибо большое, разбираюсь.
Почему-то Фокс выдает ошибку The LOCATE command must be issued before the CONTINUE command в

Код: plaintext
1.
2.
3.
4.
		LOCATE FOR LEN(ChrTran(CHR(VAL(TabDoubl.aa1))+CHR(VAL(TabDoubl.aa2))+CHR(VAL(TabDoubl.aa3))+CHR(VAL(TabDoubl.aa4))+CHR(VAL(TabDoubl.aa5)), m.lcCharString,""))=( 5 -m.lnI) && AND Recno("TabDoubl")<>Recno("BigTable123")
		 DO WHILE FOUND("TabDoubl")=.T.
			laDouble[m.lnI] = laDouble[m.lnI]+ 1 
			CONTINUE
		 ENDDO
...
Рейтинг: 0 / 0
проблема с SEEK
    #33654548
100gram
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Igor Korolyov
Практически идентичное обсуждение (касающееся лотерейной игры) было
некоторое время назад на этом форуме - никакого приемлемого (по времени
работы) способа сделать это на фоксе найдено не было

Да, я читал это обсуждение :-)
Интересно, хотя там были другие условия самой игры.
...
Рейтинг: 0 / 0
проблема с SEEK
    #33654765
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
100gramМда, нетривиально. Спасибо большое, разбираюсь.
Так ведь и задачка... Не то, чтобы тривиальная ;)

100gramПочему-то Фокс выдает ошибку The LOCATE command must be issued before the CONTINUE command в

Код: plaintext
1.
2.
3.
4.
5.
		
LOCATE FOR ...
DO WHILE FOUND("TabDoubl")=.T.
	laDouble[m.lnI] = laDouble[m.lnI]+ 1 
	CONTINUE
ENDDO


Скорее всего, забыл перед командой LOCATE перейти в нужную рабочую область. В данном случае в рабочую область TabDoubl. Т.е. нужно было

Код: plaintext
1.
2.
3.
4.
5.
6.
	
SELECT TabDoubl    && ВОТ ЭТО ОБЯЗАТЕЛЬНО
LOCATE FOR ...
DO WHILE FOUND("TabDoubl")=.T.
	laDouble[m.lnI] = laDouble[m.lnI]+ 1 
	CONTINUE
ENDDO
...
Рейтинг: 0 / 0
проблема с SEEK
    #33655967
100gram
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще раз :-)


Код: plaintext
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.
LOCAL lcCharString, lnI, laDouble( 4 )
SELECT BigTable
SCAN
*поменял на постоянное случайное число из массива:
	lcCharString = CHR(VAL(game2( 1 )))+;
	CHR(VAL(game2( 2 )))+;
	CHR(VAL(game2( 3 )))+;
	CHR(VAL(game2( 4 )))+;
	CHR(VAL(game2( 5 )))
	
	laDouble =  0 
	FOR m.lnI= 4  TO  2  STEP - 1 
		SELECT TabDoubl
*ищу по таблице
		LOCATE FOR LEN(ChrTran(CHR(VAL(TabDoubl.aa1))+;
			CHR(VAL(TabDoubl.aa2))+;
			CHR(VAL(TabDoubl.aa3))+;
			CHR(VAL(TabDoubl.aa4))+;
			CHR(VAL(TabDoubl.aa5)), m.lcCharString,""))=( 5 -m.lnI) 
*			AND Recno("TabDoubl")<>Recno("MyTab")
		DO WHILE FOUND("TabDoubl")=.T.
			laDouble[m.lnI] = laDouble[m.lnI]+ 1 
			CONTINUE
		ENDDO
	ENDFOR
*далее подсчитываю, сколько всего выпадений было.

После перебора выдает, что в тысяче записей обнаружна тысяча выпадений 4 из 5, 3 из 5, 2 из 5...
...
Рейтинг: 0 / 0
проблема с SEEK
    #33657061
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, ты даешь. Надо же самому думать! Расти над собой!

Откуда я знаю, что у тебя за функция game2(1)? Что именно она возвращает? Зачем тебе вообще SCAN по BigTable если ты берешь значения из непонятной функции game2(1)?

Кроме того, данный код имеет смысл, если в одной записи не может быть одинаковых значений. Т.е. строка со значниями 1,1,2,2,3 - не допустима. Поэкспериментируй с функцией ChrTran(). Посмотри что при этом получится.

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


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