Что нового

Подскажите как вычесть один список из другого

Baumen

Новичок
Сообщения
15
Репутация
0
Всем привет!
Подскажите мне пожалуйста!
Есть список А и список Б. Нужно получить список В - в котором есть строки из списка А, но нет строк которые есть в списке Б. Проще говоря А-Б=В

Проблема в том, что в списке А = 150000 строк. А в списке Б = 60000 строк

У меня есть программа которая делала два списка по 20000 и 10000 - 4 часа времени. А в этой задаче вообще зависла((((((

Использую обычные .txt
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
;
Код:
#include <SQLite.au3>
#include <SQLite.dll.au3>
_SQLite_Startup()
Select
	Case @error
		MsgBox(32, '', 'невозможно работать с db')
		Exit 1111
EndSelect
$hDb_mem = _SQLite_Open()
Global $a[5][1]=[[1],[2],[3],[4],[5]]
Global $b[5][1]=[[2],[3],[4],[5],[6]]
Global $aResults, $iRows, $iColumns
_SQLite_Exec($hDb_mem, 'create table if not exists tTest (a text);')
_SQLite_Exec($hDb_mem, 'create table if not exists tRest (a text);')
For $i = 0 To UBound($a)-1
	_SQLite_Exec($hDb_mem, 'insert into tTest values ("'&$a[$i][0]&'") ;')
Next
For $i = 0 To UBound($b)-1
	_SQLite_Exec($hDb_mem, 'insert into tRest values ("'&$b[$i][0]&'") ;')
Next
_SQLite_GetTable2d($hDb_mem, 'select a from tTest where a not IN (select a from tRest);', $aResults, $iRows, $iColumns)
_ArrayDisplay($aResults)
_SQLite_Close($hDb_mem)
_SQLite_Shutdown()
;
 
Автор
B

Baumen

Новичок
Сообщения
15
Репутация
0
;
Код:
#include <SQLite.au3>
#include <SQLite.dll.au3>
_SQLite_Startup()
Select
    Case @error
        MsgBox(32, '', 'невозможно работать с db')
        Exit 1111
EndSelect
$hDb_mem = _SQLite_Open()
Global $a[5][1]=[[1],[2],[3],[4],[5]]
Global $b[5][1]=[[2],[3],[4],[5],[6]]
Global $aResults, $iRows, $iColumns
_SQLite_Exec($hDb_mem, 'create table if not exists tTest (a text);')
_SQLite_Exec($hDb_mem, 'create table if not exists tRest (a text);')
For $i = 0 To UBound($a)-1
    _SQLite_Exec($hDb_mem, 'insert into tTest values ("'&$a[$i][0]&'") ;')
Next
For $i = 0 To UBound($b)-1
    _SQLite_Exec($hDb_mem, 'insert into tRest values ("'&$b[$i][0]&'") ;')
Next
_SQLite_GetTable2d($hDb_mem, 'select a from tTest where a not IN (select a from tRest);', $aResults, $iRows, $iColumns)
_ArrayDisplay($aResults)
_SQLite_Close($hDb_mem)
_SQLite_Shutdown()
;
Пишет что невозможно работать с db (использую AutoIt3.exe)
 

Tempo

AutoIT Гуру
Сообщения
616
Репутация
205
Использую обычные .txt

Еще один вариант. Не забудьте указать свои пути к файлам.
Код:
;~ AutoIt Version: 3.3.14.5
;~ Author:         Tempo
#include <File.au3>

example()

Func example()
    Local $sFileA = @ScriptDir & '\a.txt'
    Local $sFileB = @ScriptDir & '\b.txt'
    Local $sFileC = @ScriptDir & '\c.txt'

    Local $oDictB = ObjCreate('Scripting.Dictionary')
    Local $aB = FileReadToArray($sFileB)
    If @error Then Return MsgBox(0, Default, 'ошибка чтения ' & $sFileB)
    For $i = 0 To @extended - 1
        $oDictB.Item($aB[$i])
    Next

    Local $aA = FileReadToArray($sFileA)
    If @error Then Return MsgBox(0, Default, 'ошибка чтения ' & $sFileA)

    Local $iIdxC = 0
    Local $aC[@extended]
    For $i = 0 To @extended - 1
        If $oDictB.Exists($aA[$i]) Then ContinueLoop
        $aC[$iIdxC] = $aA[$i]
        $iIdxC += 1
    Next
    _FileWriteFromArray($sFileC, $aC, 0, $iIdxC - 1)
    ShellExecute($sFileC)
EndFunc   ;==>example
 
Последнее редактирование:
Автор
B

Baumen

Новичок
Сообщения
15
Репутация
0
Еще один вариант. Не забудьте указать свои пути к файлам.
Код:
;~ AutoIt Version: 3.3.14.5
;~ Author:         Tempo
#include <File.au3>

example()

Func example()
    Local $sFileA = @ScriptDir & '\a.txt'
    Local $sFileB = @ScriptDir & '\b.txt'
    Local $sFileC = @ScriptDir & '\c.txt'

    Local $oDictB = ObjCreate('Scripting.Dictionary')
    Local $aB = FileReadToArray($sFileB)
    If @error Then Return MsgBox(0, Default, 'ошибка чтения ' & $sFileB)
    For $i = 0 To @extended - 1
        $oDictB.Item($aB[$i])
    Next

    Local $aA = FileReadToArray($sFileA)
    If @error Then Return MsgBox(0, Default, 'ошибка чтения ' & $sFileA)

    Local $iIdxC = 0
    Local $aC[@extended]
    For $i = 0 To @extended - 1
        If $oDictB.Exists($aA[$i]) Then ContinueLoop
        $aC[$iIdxC] = $aA[$i]
        $iIdxC += 1
    Next
    _FileWriteFromArray($sFileC, $aC, 0, $iIdxC - 1)
    ShellExecute($sFileC)
EndFunc   ;==>example
Работает! Сделал за пару секунд. А почему такая высокая скорость? Это нормально?
 

Norm

Продвинутый
Сообщения
278
Репутация
74
Еще один вариант. Не забудьте указать свои пути к файлам.
Код:
;~ AutoIt Version: 3.3.14.5
;~ Author:         Tempo
#include <File.au3>

example()

Func example()
    Local $sFileA = @ScriptDir & '\a.txt'
    Local $sFileB = @ScriptDir & '\b.txt'
    Local $sFileC = @ScriptDir & '\c.txt'

    Local $oDictB = ObjCreate('Scripting.Dictionary')
    Local $aB = FileReadToArray($sFileB)
    If @error Then Return MsgBox(0, Default, 'ошибка чтения ' & $sFileB)
    For $i = 0 To @extended - 1
        $oDictB.Item($aB[$i])
    Next

    Local $aA = FileReadToArray($sFileA)
    If @error Then Return MsgBox(0, Default, 'ошибка чтения ' & $sFileA)

    Local $iIdxC = 0
    Local $aC[@extended]
    For $i = 0 To @extended - 1
        If $oDictB.Exists($aA[$i]) Then ContinueLoop
        $aC[$iIdxC] = $aA[$i]
        $iIdxC += 1
    Next
    _FileWriteFromArray($sFileC, $aC, 0, $iIdxC - 1)
    ShellExecute($sFileC)
EndFunc   ;==>example
Ваш код Tempo удаляет дубликаты строк просто мгновенно! :good:
Раньше я использовал регулярное выражение "(?ms)^\d+;(\V+\R*)^(?=.*\1)",
поскольку тогда это был самый быстрый способ по сравнению с перебором массива
 
Последнее редактирование:

All2khoff

Продвинутый
Сообщения
351
Репутация
65
Еще один вариант.
Ребят а кто может добавить комментарии к коду?
Код:
For $i = 0 To @extended - 1
        If $oDictB.Exists($aA[$i]) Then ContinueLoop ;если позиция найдена то записываем в файл C идем к следующей
        $aC[$iIdxC] = $aA[$i]
        $iIdxC += 1
    Next

я правильно понял?
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
Ребят а кто может добавить комментарии к коду?
$oDictB это встроенный объект Scripting.Dictionary. Метод "Exists" - Проверяет существование ключа в объекте, возвращает True или False. Это есть в справке, в русской, полное описание объекта Scripting.Dictionary и его методов.


Ранее я писал программу Compare_strings для объединения/вычитания списков, один способ с использованием Scripting.Dictionary. Функционал выведен в отдельные функции, просто взять нужную.
 
Последнее редактирование:

All2khoff

Продвинутый
Сообщения
351
Репутация
65
Спасибо большое. пока сложновато для меня)
 
Верх