Что нового

Как сделать систематизацию по строкам?

agikon

Знающий
Сообщения
789
Репутация
17
Помогите пожалуйста осуществить некую систематизацию строк (некого списка).

А именно требуется реализовать два условия:

1)чтобы новое слово которое добаляется в список добавлялось в конец таких же слов к которым оно принаддлежит по неким признакам. (этими признаками служти первое слово, то есть фамилия)

2)если новое слово не принадлежит ни к одной группе списка то оно добалялось в самый конец всего списка

На примере это выглядит как добаление слов в список, а программа должна сама выбирать куда добавлять это фИО .
Вот пример кода, где мы вписывает фио и нажимаем на "добавить".

Например вписывает "кузнецов виталий" и оно должно добавиться под кузнецов сергей которое уже есть в списке и т.д.

И пример второго условия, например вписываем совсем новое ФИО которое ещё не содержится в списке, например немцов игорь, и оно должно добавиться в самый конец списка, то есть под фомеев николай

(алфивитный порядок соблюдать не требуется ни для фамилий ни для имён, главное чтобы одинаковые фамилии добавлялись одна под одной, а совсем новые фамилии добавлялись в самый конец и т.д)

Код:
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>

Dim $aRet[1]

$hGUI = GUICreate('', 400, 400)
$nEdit1 = GUICtrlCreateEdit('смирнов алексей' & @CRLF & 'смирнов александр' & @CRLF & 'сидоров николай' & @CRLF & 'сидоров виталий' & @CRLF & 'шило максим' & @CRLF & 'шило виктория' & @CRLF & 'кузнецов сергей' & @CRLF & _
        'кунцевич марина' & @CRLF & 'фомеев николай', 10, 10, 150, 380, $ES_WANTRETURN)
$nEdit2 = GUICtrlCreateEdit('', 180, 10, 150, 20, $ES_WANTRETURN)
$nButton1 = GUICtrlCreateButton('добавить', 180, 30, 80, 20)
GUICtrlSetState(-1, $GUI_FOCUS)
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $nButton1

    EndSwitch
WEnd
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
(алфивитный порядок соблюдать не требуется ни для фамилий ни для имён, главное чтобы одинаковые фамилии добавлялись одна под одной, а совсем новые фамилии добавлялись в самый конец и т.д)
Почему просто не использовать простой сортированный список (массив, _ArraySort). Совсем новые фамилии (одинаковые) так или иначе у вас будут одна под одной. У вас то на то и выйдет, только ещё и алфавитный порядок добавится, что по моему только плюс. Все уже как говорится изобретено.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
agikon,
Попробуйте сделать примерно так.
Код:
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <ComboConstants.au3>

Opt('MustDeclareVars', 1)

Global $sTxt, $vTmp, $iSurnameSelect = -1, $oSurname, $hGUI, $iEdit, $iInput, $iButton, $iSurname, $iName, $iLabel

$oSurname = ObjCreate('Scripting.Dictionary')

If Not IsObj($oSurname) Then Exit 13
$vTmp = StringSplit(StringRegExpReplace(StringStripCR(FileRead(@ScriptDir & '\test.txt')), '\n*$', ''), @LF)
If Not @error Then
	For $i = 1 To $vTmp[0]
		$sTxt = _MyGetNewText($oSurname, $vTmp[$i])
	Next
EndIf
$vTmp = 0

$hGUI = GUICreate('', 400, 400)
$iEdit = GUICtrlCreateEdit($sTxt, 10, 10, 150, 380, BitOR($GUI_SS_DEFAULT_EDIT, $ES_WANTRETURN, $ES_READONLY))
$iInput = GUICtrlCreateInput('', 180, 10, 200, 20)
$iButton = GUICtrlCreateButton('добавить', 180, 35, 75, 20)
$iSurname = GUICtrlCreateCombo('', 180, 100, 200, 20, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST))
$iName = GUICtrlCreateCombo('', 180, 140, 200, 20, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST))
$iLabel = GUICtrlCreateLabel('', 180, 180, 200, 20)
GUICtrlSetState(-1, $GUI_FOCUS)
GUISetState()
If $oSurname.Count Then
	$vTmp = $oSurname.Keys
	_ArraySort($vTmp)
	For $sTmp In $vTmp
		GUICtrlSetData($iSurname, $sTmp)
	Next
EndIf

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $iButton
			$vTmp = GUICtrlRead($iInput)
			GUICtrlSetData($iInput, '')
			$sTxt = _MyGetNewText($oSurname, $vTmp)
			If Not $sTxt Then ContinueLoop
			GUICtrlSetData($iEdit, $sTxt)
			$sTxt = ''
			$vTmp = $oSurname.Keys
			_ArraySort($vTmp)
			GUICtrlSendMsg($iSurname, $CB_RESETCONTENT, 0, 0)
			For $sTmp In $vTmp
				GUICtrlSetData($iSurname, $sTmp)
			Next
			$vTmp = ''
		Case $iSurname
			$vTmp = GUICtrlSendMsg($iSurname, $CB_GETCURSEL, 0, 0)
			If $iSurnameSelect = $vTmp Then ContinueLoop
			$iSurnameSelect = $vTmp
			$vTmp = $oSurname.Item(GUICtrlRead($iSurname)).Keys
			_ArraySort($vTmp)
			GUICtrlSendMsg($iName, $CB_RESETCONTENT, 0, 0)
			For $sTmp In $vTmp
				GUICtrlSetData($iName, $sTmp)
			Next
		Case $iName
			GUICtrlSetData($iLabel, GUICtrlRead($iSurname) & ' ' & GUICtrlRead($iName))
	EndSwitch
WEnd

Func _MyGetNewText(ByRef $o_Surname, $s_String)
	Local $s_TxtEdit, $a_Array, $a_Array_1

	$s_TxtEdit = StringRegExpReplace(StringStripWS($s_String, 7), '[\r\n]', '')
	If Not StringRegExp($s_TxtEdit, '^[\H]+\h.+$') Then Return
	$a_Array = StringSplit($s_TxtEdit, ' ', 2)
	$s_TxtEdit = ''
	For $s_Tmp In $a_Array
		$s_TxtEdit &= StringUpper(StringLeft($s_Tmp, 1)) & StringLower(StringTrimLeft($s_Tmp, 1)) & ' '
	Next
	$a_Array = StringRegExp(StringTrimRight($s_TxtEdit, 1), '^([\H]+)\h(.+)$', 3)
	If UBound($a_Array) <> 2 Then Return
	$s_TxtEdit = ''
	If $o_Surname.Exists($a_Array[0]) Then
		$o_Surname.Item($a_Array[0]).Item($a_Array[1])
	Else
		$o_Surname.Add($a_Array[0], ObjCreate('Scripting.Dictionary'))
		$o_Surname.Item($a_Array[0]).Item($a_Array[1])
	EndIf
	$a_Array = $o_Surname.Keys
	_ArraySort($a_Array)
	For $s_Tmp In $a_Array
		$a_Array_1 = $o_Surname.Item($s_Tmp).Keys
		_ArraySort($a_Array_1)
		For $s_Tmp_1 In $a_Array_1
			$s_TxtEdit &= $s_Tmp & ' ' & $s_Tmp_1 & @CRLF
		Next
	Next
	Return StringTrimRight($s_TxtEdit, 2)
EndFunc   ;==>_MyGetNewText
test.txt:
Код:
смирнов алексей
сидоров виталий
шило максим
кунцевич марина
фомеев николай
сидоров николай
смирнов александр
шило виктория
кузнецов сергей
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
madmasles

а какие библиотеки нужны для этого кода?
а то ругается на _ArraySort()
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
madmasles
Спасибо пример шикарный, но не совсем универсален.
Английские буквы прикрутить как-то к этому коду можно?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
agikon [?]
Английские буквы прикрутить как-то к этому коду можно?
Теперь можно (код поправил), главное, чтобы был хотя бы 1 пробел.



Добавлено:
Сообщение автоматически объединено:

agikon [?]
но не совсем универсален
ИМХО, нет универсальных примеров на все случаи.
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17


Добавлено:
Сообщение автоматически объединено:

agikon [?]
но не совсем универсален
ИМХО, нет универсальных примеров на все случаи.
[/quote]
эт точно.
в любом случае задача решена, спасибо.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
:rofl:
Ну, madmasles, ну, молодец!!! (в хорошем смысле этого слова) ;D
Как лихо спрятал грабли, просто тихонько не наступал на них. :smile:

Как всегда, всё портят бабы...
Пример для тестирования подобран просто отлично! :thumbs_up: ;)
И сортировка, конечно, решает проблемы с основной массой встречающихся женских фамилий.
Но рано ж или поздно, например, в список где есть Крутиков Николай, придут Крутой Игорь и его жена.
:scratch:

Вопрос вообще-то не к madmasles, а к ТС:
а как вы вносите в список женщин с их замысловатыми фамилиями?
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333

Ну вот есть у тебя семья, фамилии у которых Умный и, соответственно, Умная.
А завтра к тебе вдруг приходит человек по фамилии Умник.
Что делать будешь со списком?
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Еще можно так решить:
Код:
$list = FileRead('spisok.txt')
$new_lastname = 'немцов' ;новая фамилия
$new_name = 'игорь' ;новое имя

$list = StringRegExpReplace($list, '(*UCP)(?i)\b' & $new_lastname & '\b.*?\r?\n', '${0}' & $new_lastname & ' ' & $new_name & @CRLF, 1)
If Not @extended Then
	$list &= @CRLF & $new_lastname & ' ' & $new_name
EndIf
ConsoleWrite($list & @CRLF)
 
Верх