Что нового

Получить в переменную крайние точки массива

Larry

Новичок
Сообщения
10
Репутация
0
Всем привет!
Помогите пожалуйста решить задачу:
У меня есть текстовый файл (1.txt) со строками вида:
0 110,1 115
1 213 160,34
2 250 400,4
3 380 420
4 410 515

В каждой строке есть три цифры (причем они не целые могут быть - через запятую). Цифры разделены разным количеством пробелов (Минимум один)
У меня есть одно известное значение $X= 180.
Количество строк может быть разным. Прочесть нужно все строки в документе.

Мне нужно перебрать все трейтии цифры в каждой строке и найти для 180 крайние ближайшие варианты. Тоесть по факту я должен буду найти 160,34 и 400,4 (так как 160,34<180<400,4)

Соответственно, нужно взять в переменные строки где есть 160,34 и 400,4

В итоге хотелось бы получить такой результат:
$a=1
$b=213
$c=160,34

$d=2
$e=250
$f=400,4

Все колонки идут строго в порядке убывания или возрастания значения. Поэтому вариант ответа только один.
 

Andrey_A

Продвинутый
Сообщения
317
Репутация
68
Код:
#include <Array.au3>

Local $sFile='D:\Test.txt',$sText=FileRead($sFile),$aRet
$sText=StringReplace($sText,',','.')
$aRet=StringRegExp($sText,'([\d.]+)',3)
_ArrayDisplay($aRet,'Массив $aRet')

Local $X=180,$n=0,$a,$b,$c,$d,$e,$f

For $i=2 To UBound($aRet)-1 Step 3
  If $aRet[$i]>$X Then
    $n=1
    ExitLoop
  EndIf
Next

If $n And $i>2 Then ; если необходимо, то сами замените точки на запятые
  $a=$aRet[$i-5]
  $b=$aRet[$i-4]
  $c=$aRet[$i-3]
  $d=$aRet[$i-2]
  $e=$aRet[$i-1]
  $f=$aRet[$i]
MsgBox(4096,'Переменные','$a =>'&$a&'<='&@CRLF&'$b =>'&$b&'<='&@CRLF&'$c =>'&$c&'<='&@CRLF&'$d =>'&$d&'<='&@CRLF&'$e =>'&$e&'<='&@CRLF&'$f =>'&$f&'<=')
EndIf
 
Последнее редактирование:
Автор
L

Larry

Новичок
Сообщения
10
Репутация
0
Код:
#include <Array.au3>

Local $sFile='D:\Test.txt',$sText=FileRead($sFile),$aRet
$sText=StringReplace($sText,',','.')
$aRet=StringRegExp($sText,'([\d.]+)',3)
_ArrayDisplay($aRet,'Массив $aRet')

Local $X=180,$n=0,$a,$b,$c,$d,$e,$f

For $i=2 To UBound($aRet)-1 Step 3
  If $aRet[$i]>$X Then
    $n=1
    ExitLoop
  EndIf
Next

If $n And $i>2 Then ; если необходимо, то сами замените точки на запятые
  $a=$aRet[$i-5]
  $b=$aRet[$i-4]
  $c=$aRet[$i-3]
  $d=$aRet[$i-2]
  $e=$aRet[$i-1]
  $f=$aRet[$i]
MsgBox(4096,'Переменные','$a =>'&$a&'<='&@CRLF&'$b =>'&$b&'<='&@CRLF&'$c =>'&$c&'<='&@CRLF&'$d =>'&$d&'<='&@CRLF&'$e =>'&$e&'<='&@CRLF&'$f =>'&$f&'<=')
EndIf
Спасибо за помощь. Но по итогу код читает все строки и выдает все переменные. А мне нужно только две крайние строки по отношению к 180
 

Andrey_A

Продвинутый
Сообщения
317
Репутация
68
А мне нужно только две крайние строки по отношению к 180
Закомментируйте строку, которая показывает принцип работы с данными и массивом
; _ArrayDisplay($aRet,'Массив $aRet')
И в итоге увидите
 

Вложения

  • 2023-04-04_192523.png
    2023-04-04_192523.png
    10.5 КБ · Просмотры: 2

Oki

Продвинутый
Сообщения
452
Репутация
62
Спасибо за помощь. Но по итогу код читает все строки и выдает все переменные. А мне нужно только две крайние строки по отношению к 180
Этот код делает именно то, что затребовано: в переменные с заданными названиями попадают требуемые заданием значения.

Этому коду не хватает только обработки особых случаев, но для того, чтобы приспособить скрипт под таковые, требуется сначала уточнить в постановке задачи, что требуется делать в нестандартных ситуациях. Дело в том, что факт (надеюсь, строгой, ибо с нестрогой всё ещё хуже) монотонности чисел (а не цифр, как ошибочно сформулировано) третьей колонки сам по себе не гарантирует, что:
  • среди чисел третьей колонки нет в точности нужного числа;
  • что нужное число не находится между никакими двумя из значений вовсе (например, будучи больше их всех, меньше их всех или равным либо минимуму, либо максимуму).
 
Автор
L

Larry

Новичок
Сообщения
10
Репутация
0
Этот код делает именно то, что затребовано: в переменные с заданными названиями попадают требуемые заданием значения.
Как же так? Не понимаю. Мне нужно показать только две строки.
Наверное я забыл указать самый важный пункт! Нужны крайние БЛИЖАЙШИЕ значения!!)

У меня есть колонка:
0 110,1 115
1 213 160,34
2 250 400,4
3 380 420
4 410 515

При исходнике 180 - я должен получить ответ ($a=1 $b=213 $c=160,34) и ($d=2 $e=250 $f=400,4) а не весь массив.
Моим ответом должно быть 6 переменных и все.

Теперь понимаю что выражение 115<180<420 тоже верно, но нужны именно ближайшие значения (160,34 и 400,4)
Сообщение автоматически объединено:

Этот код делает именно то, что затребовано: в переменные с заданными названиями попадают требуемые заданием значения.

Этому коду не хватает только обработки особых случаев, но для того, чтобы приспособить скрипт под таковые, требуется сначала уточнить в постановке задачи, что требуется делать в нестандартных ситуациях. Дело в том, что факт (надеюсь, строгой, ибо с нестрогой всё ещё хуже) монотонности чисел (а не цифр, как ошибочно сформулировано) третьей колонки сам по себе не гарантирует, что:
  • среди чисел третьей колонки нет в точности нужного числа;
  • что нужное число не находится между никакими двумя из значений вовсе (например, будучи больше их всех, меньше их всех или равным либо минимуму, либо максимуму).
Да, вы правы - не учел эти моменты. Пока я решил что буду задавать значение $x внутри моего диапазона. Не больше самого большого числа и не меньше меньшего
Сообщение автоматически объединено:

Закомментируйте строку, которая показывает принцип работы с данными и массивом
; _ArrayDisplay($aRet,'Массив $aRet')
И в итоге увидите
Простите, ввел вас в заблуждение. Нужны крайние ближайшие значения. А так вы правы, сейчас в ответ попадают все значения.
 
Последнее редактирование:

Andrey_A

Продвинутый
Сообщения
317
Репутация
68
сейчас в ответ попадают все значения.
Сейчас на выходе то что и просили "В итоге хотелось бы получить такой результат", а НЕ все значения
Вы не просили две строки.., скриншот выше.
Код:
$a=1
$b=213
$c=160,34
$d=2
$e=250
$f=400,4

Далее сами - это лишь пример - минимум, максимум - изучайте как работает автоит, тестируйте, ставьте свои условия и.т.д...
Раз вы только начали, то для начала прочитайте что такое _ArrayDisplay и MsgBox
 
Последнее редактирование:

Oki

Продвинутый
Сообщения
452
Репутация
62
Да, вы правы - не учел эти моменты. Пока я решил что буду задавать значение $x внутри моего диапазона. Не больше самого большого числа и не меньше меньшего
Если не очень волнует, влево или вправо сместятся диапазоны в случае точного попадания, то этого достаточно. Например, если для данных в стартовом посте ввести ровно 420, и не заботит, какую именно пару чисел назовёт скрипт ближайшими из двух вариантов:
  • 400,4 и 420;
  • 420 и 515.
Как же так? Не понимаю. Мне нужно показать только две строки.
Наверное я забыл указать самый важный пункт! Нужны крайние БЛИЖАЙШИЕ значения!!)
Нет, не забыл (пусть и не в стройной формулировке выражено, но мы тебя поняли правильно). А проблема вовсе не в том, что скрипт делает что-то не то, что запрошено, а в том, что нет личного понимания, что скрипт как раз и делает в точности то, что запрошено.
 
Автор
L

Larry

Новичок
Сообщения
10
Репутация
0
Закомментируйте строку, которая показывает принцип работы с данными и массивом
; _ArrayDisplay($aRet,'Массив $aRet')
И в итоге увидите
Прошу прощения! Код работает. Просто я тестировал вариант по убыванию (Наоборот)

0 410 515
1 380 420
2 250 400,4
3 213 160,34
4 110,1 115

Поэтому код мне ничего не показывал кроме массива строк! Спасибо большое. Думал разницы нет. У меня в трейтей колонке цифры по убыванию вниз идут.
Сообщение автоматически объединено:

Нет, не забыл (пусть и не в стройной формулировке выражено, но мы тебя поняли правильно). А проблема вовсе не в том, что скрипт делает что-то не то, что запрошено, а в том, что нет личного понимания, что скрипт как раз и делает в точности то, что запрошено.
Разобрался! Спасибо.
Сообщение автоматически объединено:

Поэтому код мне ничего не показывал кроме массива строк! Спасибо большое. Думал разницы нет. У меня в трейтей колонке цифры по убыванию вниз идут.
А не подскажите, что поменять в коде что бы по убыванию значения тоже мог находить?
 
Последнее редактирование:

Andrey_A

Продвинутый
Сообщения
317
Репутация
68
Del
 
Последнее редактирование:

Oki

Продвинутый
Сообщения
452
Репутация
62
Так подойдёт?
Код:
$sFile = @ScriptDir & "\1.txt"
$sText = FileRead($sFile)
$sText = StringReplace($sText, ",", ".")
$asData = StringRegExp($sText, "([\d.]+)", 3)
Dim $anData[UBound($asData)]
For $i = 0 To UBound($asData) - 1
    $anData[$i] = Number($asData[$i], 3)
Next
$iInput = InputBox("", "Input a number to search for", 180)
$iSign = 1
If $anData[UBound($anData) - 1] < $anData[2] Then
    $iSign = -1
EndIf
$i = 5
While ($iSign = 1 And $anData[$i] < $iInput) Or ($iSign = -1 And $anData[$i] > $iInput)
    $i += 3
WEnd
$a = StringReplace($asData[$i - 5], ".", ",")
$b = StringReplace($asData[$i - 4], ".", ",")
$c = StringReplace($asData[$i - 3], ".", ",")
$d = StringReplace($asData[$i - 2], ".", ",")
$e = StringReplace($asData[$i - 1], ".", ",")
$f = StringReplace($asData[$i], ".", ",")
MsgBox(4096, "", "$a = " & $a & @TAB & "$b = " & $b & @TAB & "$c = " & $c & @CRLF & "$d = " & $d & @TAB & "$e = " & $e & @TAB & "$f = " & $f)
 
Последнее редактирование:
Автор
L

Larry

Новичок
Сообщения
10
Репутация
0
Так подойдёт?
Код:
$sFile = @ScriptDir & "\1.txt"
$sText = FileRead($sFile)
$sText = StringReplace($sText, ",", ".")
$asData = StringRegExp($sText, "([\d.]+)", 3)
Dim $anData[UBound($asData)]
For $i = 0 To UBound($asData) - 1
    $anData[$i] = Number($asData[$i], 3)
Next
$iInput = InputBox("", "Input a number to search for", 180)
$iSign = 1
If $anData[UBound($anData) - 1] < $anData[2] Then
    $iSign = -1
EndIf
$i = 5
While ($iSign = 1 And $anData[$i] < $iInput) Or ($iSign = -1 And $anData[$i] > $iInput)
    $i += 3
WEnd
$a = StringReplace($asData[$i - 5], ".", ",")
$b = StringReplace($asData[$i - 4], ".", ",")
$c = StringReplace($asData[$i - 3], ".", ",")
$d = StringReplace($asData[$i - 2], ".", ",")
$e = StringReplace($asData[$i - 1], ".", ",")
$f = StringReplace($asData[$i], ".", ",")
MsgBox(4096, "", "$a = " & $a & @TAB & "$b = " & $b & @TAB & "$c = " & $c & @CRLF & "$d = " & $d & @TAB & "$e = " & $e & @TAB & "$f = " & $f)
Благодарю за помощь! Работает
 
Верх