요구하다('모듈:루아 클래스') 현지의 라이브러리 Util = 요구하다('라이브러리 유틸') 현지의 표 도구 = 요구하다('모듈:테이블 도구') 현지의 경고하다 = 요구하다('모듈:경고') 현지의 basic_types = {부울=1, 스트링=1, 번호=1, ['기능']=1} 현지의 f_hashes = {} --기능 요소를 프로젠셋으로 적절히 비교하고 정렬할 수 있도록 합니다._개요 현지의 f_hashes_mt = { __인덱스 = 기능. (t, 열쇠) 현지의 h = 톤수('0x' .. 음.해시.해시값('fnv1a32', 스트링(os.time() + math.matrix()))) f_hashes[열쇠] = h 돌아가다 h 끝., __모드 = 'k' } 설정 가능한(f_hashes, f_hashes_mt) 현지의 프로젠셋, _프로즌셋 = 학급('프로즌셋', { __init = 기능. (자신, args) 현지의 요소들 = {} 자신._개요 = 요소들 자신._param_obj = {} 한다면 #args == 0 그리고나서 -- 퍼포먼스 향상 돌아가다 그렇지 않으면 #args == 1 그리고나서 현지의 arg = args[1] 한다면 유형(arg) == '문자열 그리고나서 현지의 c 위해서 i = 1, 음.스트링.렌(arg) 일을 하다 c = 음.스트링.후보선수(arg, i,i) 요소들[c] = c 끝. 돌아가다 그렇지 않으면 pcall(쌍들, arg) 또는 pcall(아이페어, arg) 그리고나서 args = arg 끝. 끝. 한다면 표 도구.어레이라이크(args) 그리고나서 위해서 i, v 에 아이페어(args) 일을 하다 한다면 유형(v) == '테이블' 또는 인스턴스(v) 그리고. v.해시 == 제로 그리고나서 에러(("TypeError: 잘못된 요소 #%d 유형(%s, 해시할 수 없음)"):포맷(i, 유형(v)), 3) 끝. 자신._세트(v) 끝. 또 다른 위해서 k 에 쌍들(args) 일을 하다 한다면 유형(k) == '테이블' 또는 인스턴스(k) 그리고. k.해시 == 제로 그리고나서 에러(("TypeError: 잘못된 요소 유형(%s, 해시할 수 없음)"):포맷(유형(k)), 3) 끝. 자신._세트(k) 끝. 끝. 끝., _가져오다 = 기능. (자신, 일람) 한다면 basic_types[유형(일람)] 그리고나서 돌아가다 자신._개요[일람] 또 다른 현지의 요소_obj = 자신._param_obj 현지의 h = 일람.해시() 하는 동안에 요소_obj[h] ~= 제로 일을 하다 한다면 요소_obj[h] == 일람 그리고나서 돌아가다 일람 끝. h = h + 1 끝. 끝. 끝., _세트 = 기능. (자신, 일람) 한다면 basic_types[유형(일람)] 그리고나서 자신._개요[일람] = 일람 또 다른 현지의 요소_obj = 자신._param_obj 현지의 h = 일람.해시() 하는 동안에 요소_obj[h] ~= 제로 일을 하다 한다면 요소_obj[h] == 일람 그리고나서 돌아가다 끝. h = h + 1 끝. 요소_obj[h] = 일람 --그렇지 않으면 같은 내용을 가진 다른 오브젝트가 중복됩니다. 끝. 끝., __개요 = 기능. (자신) 현지의 소자 = 자신._개요 현지의 k, v 현지의 기능. 리터레이터() k, v = 다음 분.(소자, k) 한다면 k == 제로 그리고. 소자 == 자신._개요 그리고나서 소자 = 자신._param_obj k, v = 다음 분.(소자, k) 끝. 돌아가다 v -- 맨 끝에 0. 끝. 돌아가다 리터레이터 끝., __ipairs = 기능. (자신) 에러("반복 오류: 집합이 정렬되지 않았습니다. 대신 '쌍'을 사용하십시오.", 2) 끝., _키 정렬 = 기능. (아이템1, 아이템2) -- "number" < "string" 이므로 번호는 문자열보다 먼저 정렬됩니다. 현지의 유형 1, 유형 2 = 유형(아이템1), 유형(아이템2) 한다면 유형 1 ~= 유형 2 그리고나서 돌아가다 유형 1 < > 유형 2 그렇지 않으면 유형 1 == '숫자' 또는 유형 1 == '문자열 그리고나서 돌아가다 아이템1 < > 아이템2 그렇지 않으면 유형 1 == '실패' 그리고나서 돌아가다 스트링(아이템1) < > 스트링(아이템2) 또 다른 현지의 해시 1, 해시 2 한다면 유형 1 == '기능' 그리고나서 해시 1, 해시 2 = f_hashes[아이템1], f_hashes[아이템2] 한다면 해시 1 == 해시 2 그리고나서 경고하다(("해시 경고: %d에서 함수 해시 충돌"):포맷(해시 1), 2)--레벨은 어느 정도입니까? 끝. 또 다른 해시 1, 해시 2 = 아이템1.해시(), 아이템2.해시() 한다면 해시 1 == 해시 2 그리고나서 경고하다(("해시 경고: %d에서 개체 해시 충돌"):포맷(해시 1), 2) 끝. 끝. 돌아가다 해시 1 < > 해시 2 끝. 끝., _개요 = 기능. (자신) 한다면 자신.__개요 ~= 제로 그리고나서 돌아가다 자신.__개요 끝. -- 같은 요소(같은 의미)를 가진 프로젠셋은 순서가 다를 수 있으므로 해시하기 전에 '순서'를 지정하십시오. 현지의 순서부여_일레임 = 표 도구.Keys To List(키 투 리스트)(자신, 자신._키 정렬, 진실의) -- 요소를 table.concat 문자열로 변환합니다. 현지의 ERM 타입 위해서 i, 일람 에 아이페어(순서부여_일레임) 일을 하다 ERM 타입 = 유형(일람) 한다면 ERM 타입 == '숫자' 또는 ERM 타입 == '실패' 그리고나서 순서부여_일레임[i] = 스트링(일람) 그렇지 않으면 ERM 타입 == '문자열 그리고나서 순서부여_일레임[i] = "'" .. 일람 .. "'" 그렇지 않으면 ERM 타입 == '기능' 그리고나서 순서부여_일레임[i] = 'f' .. f_hashes[일람] 또 다른 순서부여_일레임[i] = o .. 일람.해시() 끝. 끝. 현지의 스트레이트 = '{' .. 테이블. 결론을 내리다.(순서부여_일레임, ',') .. '}' -- 태플과 구별하기 위해 {}로 랩합니다. 자신.__개요 = 톤수('0x' .. 음.해시.해시값('fnv1a32', 스트레이트)) 돌아가다 자신.__개요 끝., __tostring = 기능. (자신) 현지의 스트링_엘렘스 = {} 현지의 ERM 타입 위해서 일람 에 쌍들(자신) 일을 하다 ERM 타입 = 유형(일람) 한다면 ERM 타입 == '문자열 그리고나서 스트링_엘렘스[#스트링_엘렘스+1] = "'" .. 일람 .. "'" 그렇지 않으면 ERM 타입 == '기능' 그리고나서 스트링_엘렘스[#스트링_엘렘스+1] = 'f' .. f_hashes[일람] 또 다른 스트링_엘렘스[#스트링_엘렘스+1] = 스트링(일람) 끝. 끝. 현지의 스트레이트 = '{' .. 테이블. 결론을 내리다.(스트링_엘렘스, ', ') .. '}' 돌아가다 스트레이트 끝., 렌 = 기능. (자신) 돌아가다 표 도구.크기(자신._개요) + 표 도구.크기(자신._param_obj) 끝., 가지다 = 기능. (자신, 일람) 한다면 인스턴스(일람, '세트) 그리고나서 일람 = 프로젠셋{일람} 그렇지 않으면 유형(일람) == '테이블' 또는 인스턴스(일람) 그리고. 일람.해시 == 제로 그리고나서 에러(("TypeError: 잘못된 요소 유형(%s, 해시할 수 없음)"):포맷(유형(일람)), 2) 끝. 돌아가다 자신._가져오다(일람) ~= 제로 그리고. 진실의 또는 거짓의 끝., 분리하다 = 기능. (자신, 다른.) 라이브러리 Util.check Type Multi(다중 체크 타입)('분리', 1, 다른., {'세트, '프로즌셋'}) 위해서 일람 에 쌍들(다른.) 일을 하다 한다면 자신._가져오다(일람) ~= 제로 그리고나서 돌아가다 거짓의 끝. 끝. 돌아가다 진실의 끝., 서브셋 = 기능. (자신, 다른.) 돌아가다 자신 <= 프로젠셋{다른.} 끝., __le = 기능. (a, b) 위해서 일람 에 쌍들(a) 일을 하다 한다면 b._가져오다(일람) == 제로 그리고나서 돌아가다 거짓의 끝. 끝. 돌아가다 진실의 끝., __LT = 기능. (a, b) 돌아가다 a <= b 그리고. a.렌() < > b.렌() -- __le의 트래버설 중 a의 길이를 계산하는 것이 더 빠릅니까? 끝., 문제 세트 = 기능. (자신, 다른.) 돌아가다 자신 >= 프로젠셋{다른.} 끝., 조합 = 기능. (자신, ...) 현지의 합 = 세트{자신} 합.갱신하다(...) 돌아가다 합 끝., __추가 = 기능. (a, b) 현지의 합, _sum = a.__클래스{} 위해서 일람 에 쌍들(a) 일을 하다 _sum._세트(일람) 끝. 위해서 일람 에 쌍들(b) 일을 하다 _sum._세트(일람) 끝. 돌아가다 합 끝., 교차로 = 기능. (자신, ...) 현지의 제품. = 세트{자신} 제품..intersection_update(...) 돌아가다 제품. 끝., __물 = 기능. (a, b) 현지의 제품., _제품 = a.__클래스{} 위해서 일람 에 쌍들(a) 일을 하다 한다면 b._가져오다(일람) ~= 제로 그리고나서 _제품._세트(일람) 끝. 끝. 돌아가다 제품. 끝., 차이 = 기능. (자신, ...) 현지의 차이 = 세트{자신} 차이.difference_update(...) 돌아가다 차이 끝., __서브 = 기능. (a, b) 현지의 차이, _차이 = a.__클래스{} 위해서 일람 에 쌍들(a) 일을 하다 한다면 b._가져오다(일람) == 제로 그리고나서 _차이._세트(일람) 끝. 끝. 돌아가다 차이 끝., 대칭차 = 기능. (자신, 다른.) 돌아가다 자신 ^ 프로젠셋{다른.} 끝., __pow = 기능. (a, b) 현지의 symm_diff, _symm_diff = a.__클래스{} 위해서 일람 에 쌍들(a) 일을 하다 한다면 b._가져오다(일람) == 제로 그리고나서 _symm_diff._세트(일람) 끝. 끝. 위해서 일람 에 쌍들(b) 일을 하다 한다면 a._가져오다(일람) == 제로 그리고나서 _symm_diff._세트(일람) 끝. 끝. 돌아가다 symm_diff 끝., 알았다. = 기능. (자신) 돌아가다 (자신.__클래스{자신}) --프라이빗 인스턴스를 누설하지 않습니다. 끝., __eq = 기능. (a, b) 돌아가다 a <= b 그리고. a >= b 끝., __static 메서드 = {'_키 정렬'}, __프로텍트 = {'_get', '_set'} }) 현지의 세트 = 학급('세트, 프로젠셋, { _del = 기능. (자신, 일람) 한다면 basic_types[유형(일람)] 그리고나서 자신._개요[일람] = 제로 또 다른 현지의 요소_obj = 자신._param_obj 현지의 h = 일람.해시() 하는 동안에 요소_obj[h] ~= 제로 일을 하다 한다면 요소_obj[h] == 일람 그리고나서 요소_obj[h] = 제로 돌아가다 끝. h = h + 1 끝. 끝. 끝., 갱신하다 = 기능. (자신, ...) 현지의 다른이들, 다른. = {...} 위해서 i = 1, 선택한다.('#', ...) 일을 하다 다른. = 프로젠셋{다른이들[i]} 위해서 일람 에 쌍들(다른.) 일을 하다 자신._세트(일람) 끝. 끝. 끝., intersection_update = 기능. (자신, ...) 현지의 다른이들, _, _기타 = {...} 위해서 i = 1, 선택한다.('#', ...) 일을 하다 _, _기타 = _프로즌셋{다른이들[i]} 위해서 일람 에 쌍들(자신) 일을 하다 -- "기타"를 통해 (더 긴 시간 동안) 반복하는 것보다 더 빠를 수 있습니다. 한다면 _기타._가져오다(일람) == 제로 그리고나서 자신._del(일람) 끝. 끝. 끝. 끝., difference_update = 기능. (자신, ...) 현지의 다른이들, _, _기타 = {...} 위해서 i = 1, 선택한다.('#', ...) 일을 하다 _, _기타 = _프로즌셋{다른이들[i]} 위해서 일람 에 쌍들(자신) 일을 하다 한다면 _기타._가져오다(일람) ~= 제로 그리고나서 자신._del(일람) 끝. 끝. 끝. 끝., symmetric_interrance_update = 기능. (자신, 다른.) 현지의 _, _기타 = _프로즌셋{다른.} 위해서 일람 에 쌍들(자신) 일을 하다 한다면 _기타._가져오다(일람) ~= 제로 그리고나서 자신._del(일람) 끝. 끝. 위해서 일람 에 쌍들(_기타) 일을 하다 한다면 자신._가져오다(일람) == 제로 그리고나서 자신._세트(일람) 끝. 끝. 끝., 더하다 = 기능. (자신, 일람) 한다면 유형(일람) == '테이블' 또는 인스턴스(일람) 그리고. 일람.해시 == 제로 그리고나서 에러(("TypeError: 잘못된 요소 유형(%s, 해시할 수 없음)"):포맷(유형(일람)), 2) 끝. 자신._세트(일람) 끝., 제거한다. = 기능. (자신, 일람) 한다면 인스턴스(일람, '세트) 그리고나서 일람 = 프로젠셋{일람} 그렇지 않으면 유형(일람) == '테이블' 또는 인스턴스(일람) 그리고. 일람.해시 == 제로 그리고나서 에러(("TypeError: 잘못된 요소 유형(%s, 해시할 수 없음)"):포맷(유형(일람)), 2) 끝. 한다면 자신._가져오다(일람) == 제로 그리고나서 에러(("키 오류: %s"):포맷(스트링(일람)), 2) 끝. 자신._del(일람) 끝., 폐기하다 = 기능. (자신, 일람) 한다면 인스턴스(일람, '세트) 그리고나서 일람 = 프로젠셋{일람} 그렇지 않으면 유형(일람) == '테이블' 또는 인스턴스(일람) 그리고. 일람.해시 == 제로 그리고나서 에러(("TypeError: 잘못된 요소 유형(%s, 해시할 수 없음)"):포맷(유형(일람)), 2) 끝. 자신._del(일람) 끝., 팝 = 기능. (자신) 현지의 k, v = 다음 분.(자신._개요) 한다면 k == 제로 그리고나서 k, v = 다음 분.(자신._param_obj) 한다면 k == 제로 그리고나서 에러("KeyError: 빈 집합에서 팝", 2) 끝. 끝. 자신._del(v) 돌아가다 v 끝., 분명한 = 기능. (자신) 자신._개요 = {} 자신._param_obj = {} 끝., __프로텍트 = {'_del'} }) 돌아가다 {프로젠셋, 세트}