Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Несколько затруднений про массивы (Pascal) (http://forum.oszone.net/showthread.php?t=330390)

blackeangel 10-10-2017 15:32 2769615

Несколько затруднений про массивы (Pascal)
 
Вопрос номер один:
Пишу функцию, она должна принимать двумерный текстовый массив. Как это описать в скобочках?
Вопрос номер 2
Как определить размеры двумерного массива? Один параметр знаю: Length(mass),а как второй?
Вопрос номер 3:
Как создать двумерный массив на основе уже имеющегося? Типа дублера, либо как вариант одинаковый по второму параметру.

Прошу прощения за нубские вопросы, но паскаль был в школе. Сейчас пишу в Lazarus.
___

Busla 10-10-2017 19:30 2769661

  1. передать ссылку на массив
  2. "определить" - это "узнать" или "задать"? Врочем, это одно и то же: размер массива - константа.
  3. никак

blackeangel 10-10-2017 19:37 2769665

Busla,
1. Так?
Код:

function DelRow(A,B: array of string):array of string;
2. Определить == узнать, причем и кол-во строк и кол-во столбцов
Так?
Код:

"Высота" = Length(ms);
"(ширина" = Length(ms[0]);

3. Странно, в других языках есть, а тут нет. Сомнительно.
Может не так выразился. Создать новый массив имеющий такую же размерность как у другого массива?
Тогда это будет так?
Код:

new_mass:array[0..Length(old_mass),0..Length(old_mass[0])] of string;

Busla 12-10-2017 17:08 2770094

blackeangel, массивы в Pascal (в Lasarus в том числе) определяются на этапе компиляции
Код:

program
...
var
  variablename: array [startindex..endindex] of type;
begin

а это:
Код:

var
  ...
  variablename: array of type;

уже другой язык - ObjectPascal и т.п., и не массивы как таковые

Iska 12-10-2017 17:24 2770097

Busla, ему любое подойдёт, лишь бы работало. Суть в том, что определение размера массива должно происходить динамически, в процессе исполнения приложения.

P.S. Я уже несколько раз предлагал коллеге blackeangel перейти к словарям/коллекциям, но он не видит в этом нужды.

blackeangel 12-10-2017 18:38 2770112

Iska, как оказалось на паскале невозможно динамически создавать массивы по ходу кода.

И я рад Вас видеть ;)
На счёт словарей/коллекций/эрей листов.
Если вы мне обьясните как это работает простым деревенским языком, то пойму и буду их использовать.
Если массивы окружают нас в жизни, то словарь только толковый или орфографический.
Массивы это тетрадь в клетку, таблица экселя, 9 стаканов на столе(3х3), графический ключ на телефоне(3х3) и т.д.

Iska 12-10-2017 21:43 2770177

Цитата:

Цитата blackeangel
Iska, как оказалось на паскале невозможно динамически создавать массивы по ходу кода. »

Как это невозможно? На чистом Паскале — да, но неужто в Object Pascal нет динамических массивов? Вот же ж коллега Busla писал выше об этом:
Dynamic arrays
Dynamic array - Free Pascal wiki

Iska 13-10-2017 02:22 2770233

Цитата:

Цитата blackeangel
Если вы мне обьясните как это работает простым деревенским языком, то пойму и буду их использовать. »

Простым языком… Ну, давайте попробуем.

Простейший вариант реализован в WSH, в VB и в VBA. Пример демонстрации свойств и методов словаря на WSH, исполнять под консольным cscript.exe:
Скрытый текст
Код:

Option Explicit

Dim objDictionary
Dim strKey, strValue
Dim arrKeys, arrValues
Dim i


Set objDictionary = WScript.CreateObject("Scripting.Dictionary")

' Сравнение ключей будем производить в текстовом виде
' (тогда будет игнорироваться различие строчных и заглавных букв)
objDictionary.CompareMode = vbTextCompare

' Заполняем словарь парами Ключ/Значение
objDictionary.Add "Ключ1", "Значение1"
objDictionary.Add "Ключ2", "Значение2"
objDictionary.Add "Ключ3", "Значение3"
objDictionary.Add "Ключ4", "Значение4"
objDictionary.Add "Ключ5", "Значение5"
objDictionary.Add "Ключ6", "Значение6"

' Добавим ещё три пары Ключ/Значение
objDictionary.Add "Ключ7", "Значение7"
objDictionary.Add "Ключ8", "Значение8"
objDictionary.Add "Ключ9", "Значение9"

' Заменим значение ключей Ключ3 и Ключ4
objDictionary.Item("Ключ3") = "Мама мыла раму"
objDictionary.Item("Ключ4") = "Рабы не мы, мы не рабы"

' Удалим две пары Ключ/Значение
objDictionary.Remove "Ключ4"
objDictionary.Remove "Ключ5"

' Попытка добавления уже существующего ключа или удаления несуществующего
' вызовет ошибку времени исполнения.
' Чтобы этого избежать, мы можем проверять существование ключа перед данными операциями
If Not objDictionary.Exists("Ключ10") Then
        objDictionary.Add "Ключ10", "Значение10"
End If

If objDictionary.Exists("Ключ6") Then
        objDictionary.Remove "Ключ6"
End If

' Тип значения словаря
WScript.Echo TypeName(objDictionary)
WScript.Echo

' Количество элементов словаря
WScript.Echo objDictionary.Count
WScript.Echo

' Выводим содержимое словаря в виде пары Ключ/Значение, перебирая ключи
For Each strKey In objDictionary.Keys
        WScript.Echo strKey, objDictionary.Item(strKey)
Next
WScript.Echo

' К предыдущему: тип значения objDictionary.Keys — массив типа Variant
WScript.Echo TypeName(objDictionary.Keys)
WScript.Echo

' Поэтому можно задействовать не только цикл вида For Each, но и обычный For…To…Next,
' несмотря на то, что обратиться напрямую по индексу к паре Ключ/Значение нельзя
' (только через промежуточную переменную, иначе лексический анализатор WSH спотыкается)
arrKeys = objDictionary.Keys

For i = LBound(arrKeys) To UBound(arrKeys)
        WScript.Echo i, arrKeys(i), objDictionary.Item(arrKeys(i))
Next
WScript.Echo

' Выводим только значения:
For Each strValue In objDictionary.Items
        WScript.Echo strValue
Next
WScript.Echo

' И аналогично — через For…To…Next
arrValues = objDictionary.Items

For i = LBound(arrValues) To UBound(arrValues)
        WScript.Echo i, arrValues(i)
Next
WScript.Echo

' Выводим пары Ключ/Значение словаря Ключ2 и Ключ10
WScript.Echo objDictionary.Item("Ключ2")
WScript.Echo objDictionary.Item("Ключ10")
WScript.Echo

' Хотя обычно с индексами в словарях не работают, но можно сделать и так
' Выводим третью и четвёртую пары словаря (памятуя, что нумерация массивов идёт с нуля)
WScript.Echo arrKeys(2), objDictionary.Item(arrKeys(2))
WScript.Echo arrKeys(3), objDictionary.Item(arrKeys(3))
WScript.Echo

' Удалим все пары Ключ/Значение
objDictionary.RemoveAll

Set objDictionary = Nothing

WScript.Quit 0


Пример практической реализации — подсчёт количества одинаковых символов в произвольном тексте (дабы не усложнять кодировками, чтением из файла — используем банальную строковую переменную):
Скрытый текст
Код:

Option Explicit

Dim strText, strSymbol

Dim objDictionary
Dim strKey
Dim i


strText = _
        "И я рад Вас видеть" & _
        "На счёт словарей/коллекций/эрей листов." & _
        "Если вы мне обьясните как это работает простым деревенским языком, то пойму и буду их использовать." & _
        "Если массивы окружают нас в жизни, то словарь только толковый или орфографический." & _
        "Массивы это тетрадь в клетку, таблица экселя, 9 стаканов на столе(3х3), графический ключ на телефоне(3х3) и т.д."

Set objDictionary = WScript.CreateObject("Scripting.Dictionary")

For i = 1 To Len(strText)
        ' Извлекаем из строки очередной символ
        strSymbol = Mid(strText, i, 1)
       
        ' Если его ещё нет в словаре…
        If Not objDictionary.Exists(strSymbol) Then
                ' …то добавляем его и задаём ему значение количества равным 1
                objDictionary.Add strSymbol, 1
        Else
                ' …иначе увеличиваем его значение количества на единицу
                objDictionary.Item(strSymbol) = objDictionary.Item(strSymbol) + 1
        End If
Next


WScript.Echo "Symbol", vbTab, "Count"
WScript.Echo "======", vbTab, "====="

For Each strKey In objDictionary.Keys
        WScript.Echo strKey, vbTab, objDictionary.Item(strKey)
Next

objDictionary.RemoveAll

Set objDictionary = Nothing

WScript.Quit 0


В более серьёзных языках, особенно в .Net, добавлены классы, которые не только полностью покрывают такой тип данных как Словарь, но и заметным образом расширяют его возможности, например прямое обращение к паре по индексу (поскольку класс сделан перечислимым), проверка существования значения, сортировка пар и прочее. Что-то похожее есть и во Free Pascal.

Ylik 05-12-2017 12:14 2782442

Определите полностью тип передаваемых в функцию данных.
Так что бы в заголовке функции было что-то типа
Код:

function FunctionName(var Name:TypeName):ReturnTypeName
Не знаю как в Lazarus, а в классическом Паскале вроде нельзя описывать тип переменных сложными структурами типа массивов или записей.


Время: 12:11.

Время: 12:11.
© OSzone.net 2001-