Что нового

[Данные, строки] Сумма из текстового файла с под.итогами

AlexVong

Новичок
Сообщения
112
Репутация
1
Версия AutoIt: 3.3.8.1

Описание: Необходимо посчитать сумму всех вторых значений из каждой строки текстового файла разделенных ";" и вывести результат сообщением на экран с указанием суммы для каждой конкретноой группы 1-го и 3-го значения. Например для файла-примера сообщение было бы следующим -
Код:
EUR - Z - 713.52
RUB - W - 91.1
RUB - Z - 45
USD - Z - 7.25

Примечания: Оригинальные файлы по 10-20 тыс.строк, 1-е и 3-е значение в строке может быть каким угодно, 2-е всегда числовое значение.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
AlexVong

Код:
#include <Array.au3>

Local $a2dArray, $sText = ''
$sFilePath = @ScriptDir & '\str.txt'

_FileReadToArray2D($sFilePath, $a2dArray, Default)

For $i = 1 To $a2dArray[0][0]
	$a2dArray[$i][0] = $a2dArray[$i][0] & '^' & $a2dArray[$i][2]
Next

_ArraySort($a2dArray, 1, 1, 0, 0)

For $j = 1 To $a2dArray[0][0]
	If $a2dArray[$j][0] = $a2dArray[$j - 1][0] Then
		$a2dArray[$j][1] += $a2dArray[$j - 1][1]
		$a2dArray[$j - 1][0] = ''
		$a2dArray[$j - 1][1] = ''
		$a2dArray[$j - 1][2] = ''
	EndIf
Next

$a2dArray = _DeleteEmptyRows($a2dArray)
$a2dArray[0][0] = UBound($a2dArray) - 1

For $i = 1 To $a2dArray[0][0]
	$aSplit = StringSplit($a2dArray[$i][0], '^')
	$a2dArray[$i][0] = $aSplit[1]
Next

_ArrayDisplay($a2dArray)

Func _DeleteEmptyRows($aArray)
	Local $Rows = UBound($aArray, 1)
	Local $Cols = UBound($aArray, 2)
	Local $aTemp[$Rows][$Cols]
	Local $not_empty
	Local $Count = 0
	For $Y = 0 To $Rows - 1
		$not_empty = 0
		For $X = 0 To $Cols - 1
			$aTemp[$Count][$X] = $aArray[$Y][$X]
			If $aArray[$Y][$X] <> '' Then $not_empty = BitOR($not_empty, 1)
		Next
		If $not_empty Then $Count += 1
	Next
	ReDim $aTemp[$Count][$Cols]
	Return $aTemp
EndFunc   ;==>_DeleteEmptyRows

Func _FileReadToArray2D($sFilePath, ByRef $aArray, $sDelimiter = Default)
	$aArray = 0
	Local $aSRE = StringRegExp(FileRead($sFilePath) & @LF, '([^\r\n]*)(?:\r\n|\n|\r)(?:[\r\n]$)?', 3) ; By DXRW4E.
	If @error Then
		Return SetError(1, 0, 0)
	EndIf
	Local $iUBound = UBound($aSRE, 1)
	If $sDelimiter = Default Then
		$sDelimiter = ';'
	EndIf
	Local $aSplit = StringSplit($aSRE[0], $sDelimiter)
	If @error Then
		Return SetError(2, 0, 0)
	EndIf

	Local $aArrayTemp[$iUBound + 1][$aSplit[0]] = [[0]]
	For $i = 0 To $iUBound - 1
		$aSplit = StringSplit($aSRE[$i], $sDelimiter)
		If @error Then
			ContinueLoop
		EndIf

		$aArrayTemp[0][0] += 1
		For $j = 1 To $aSplit[0]
			$aArrayTemp[$aArrayTemp[0][0]][$j - 1] = $aSplit[$j]
		Next
	Next
	$aArray = $aArrayTemp
	$aArrayTemp = 0
EndFunc   ;==>_FileReadToArray2D
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
если для данного конкретного случая то можно и так
Код:
#include <String.au3>
#include <array.au3>
Local $all_rz, $all_rw, $all_ez, $all_ew, $all_uz, $all_uw
Local $array[1]

$fo = FileOpen('str.txt')

While 1
	$frl = FileReadLine($fo)
	If @error = -1 Then ExitLoop
	$strin_r = StringInStr($frl, 'RUB')
	$strin_u = StringInStr($frl, 'USD')
	$strin_e = StringInStr($frl, 'EUR')
	If $strin_r Then
		$strin_rz = StringInStr($frl, 'Z')
		$strin_rw = StringInStr($frl, 'w')
		If $strin_rz Then
			$d_rz = _StringBetween($frl, ';', ';')
			$all_rz += $d_rz[0]
		ElseIf $strin_rw Then
			$d_rw = _StringBetween($frl, ';', ';')
			$all_rw += $d_rw[0]
		EndIf
	ElseIf $strin_u Then
		$strin_uz = StringInStr($frl, 'Z')
		$strin_uw = StringInStr($frl, 'w')
		If $strin_uz Then
			$d_uz = _StringBetween($frl, ';', ';')
			$all_uz += $d_uz[0]
		ElseIf $strin_uw Then
			$d_uw = _StringBetween($frl, ';', ';')
			$all_uw += $d_uw[0]
		EndIf
	ElseIf $strin_e Then
		$strin_ez = StringInStr($frl, 'Z')
		$strin_ew = StringInStr($frl, 'w')
		If $strin_ez Then
			$d_ez = _StringBetween($frl, ';', ';')
			$all_ez += $d_ez[0]
		ElseIf $strin_ew Then
			$d_ew = _StringBetween($frl, ';', ';')
			$all_ew += $d_ew[0]
		EndIf
	EndIf
WEnd
FileClose($fo)
If Not $all_ew = 0 Then
	_ArrayAdd($array, 'EUR - W - ' & $all_ew)
	EndIf
If Not $all_ez = 0 Then
	_ArrayAdd($array, 'EUR - Z - ' & $all_ez)
	EndIf
If Not $all_rz = 0 Then
	_ArrayAdd($array, 'RUB - Z - ' & $all_rz)
	EndIf
If Not $all_rw = 0 Then
	_ArrayAdd($array, 'RUB - W - ' & $all_rw )
	EndIf
If Not $all_uz = 0 Then
	_ArrayAdd($array, 'USD - Z - ' & $all_uz)
	EndIf
If Not $all_uw = 0 Then
	_ArrayAdd($array, 'USD - W - ' & $all_uw)
	EndIf

_ArrayDisplay($array)
работает быстрее, чем предыдущий код. проверено на файле с 10 000 строк
 
Автор
A

AlexVong

Новичок
Сообщения
112
Репутация
1
Спасибо!!! Оба варианта работают отлично !!!
 
Верх