برنامه نویسی 37 بازدید

در این مقاله به بررسی ساختمان داده و الگوریتم‌های مختلفی که در زبان برنامه‌نویسی سوئیفت وجود دارند می‌پردازیم و بیشترین تمرکز ما روی آرایه‌ها خواهد بود.

ساختمان داده چیست؟

ساختمان‌های داده بلوک‌های سازنده‌ای هستند که برای ساخت یک سیستم مورد استفاده قرار می‌گیرند. این بلوک‌ها امکان توسعه سیستم‌های مؤثر، مقیاس‌پذیر، و قابل نگهداری را فراهم می‌سازند. آن‌ها همچنین ابزاری برای سازماندهی و ارائه داده‌ها در مواردی که لازم است بین موجودیت‌های مختلف به اشتراک درآیند، ارائه می‌کنند. ساختمان‌های داده نه‌تنها موجب سهولت فرایند اشتراک داده‌ها می‌شوند، بلکه نگهداری، مرتب‌سازی و جستجوی داده‌ها را نیز آسان‌تر می‌سازند.

همه اپلیکیشن‌های نرم‌افزاری، صرف‌نظر از سیستمی که برای توسعه آن‌ها استفاده می‌شود، بر مبنای داده ساخته شده‌اند. در توسعه اغلب اپلیکیشن‌های مدرن از «رابط‌های برنامه‌نویسی اپلیکیشن» (API) برای کمک به ایجاد محصول‌های شگفت‌انگیز استفاده می‌شود؛ با این وجود API ها هم از ساختمان و الگوریتم داده‌ها استفاده می‌کنند.

دو ساختمان داده بنیادی وجود دارند که برای توسعه هر نرم‌افزاری ضروری محسوب می‌شوند: آرایه‌ها و لیست‌های پیوندی. این ساختمان‌های داده برای ایجاد ساختمان‌های داده پیشرفته‌تر ضروری هستند. در این مقاله در مورد آرایه‌ها صحبت خواهیم کرد.

آرایه چیست؟

آرایه مجموعه مرتب و با دسترسی تصادفی است که به صورتی پیوسته داده‌ها را در بلوک‌های مجاوری از حافظه ذخیره می‌سازد. آرایه یکی از شناخته‌شده‌ترین ساختمان‌های داده محسوب می‌شود و در اغلب زبان‌های برنامه‌نویسی مورد استفاده قرار می‌گیرد. آرایه یک‌بُعدی با استفاده از نمادگذاری ریاضیاتی به صورت زیر نمایش می‌یابد:

بازنمایی ریاضیاتی از آرایه یک‌بعدی

که a0 نماینده عنصر نخست آرایه و ai نماینده عنصر i+1-ام آرایه است.

نوع دیگری از آرایه به نام آرایه چندبُعدی نیز وجود دارد. یک ماتریس چندبُعدی به صوت آرایه چندبُعدی پیاده‌سازی می‌شود. در مثال زیر یک ماتریس دوبُعدی به تصویر درآمده است که به صورت یک آرایه دوبُعدی عمل می‌کند.

بازنمایی ریاضیاتی آرایه دوبُعدی

a00 نماینده عنصر ردیف نخست و ستون نخست است. به طور مشابه aij نماینده عنصر ردیف i و ستون j است.

در سوئیفت سه روش برای اعلان و مقداردهی اولیه یک آرایه وجود دارد:

  1. شکل کامل که از نمادگذاری <Array<ElementType استفاده می‌کند.
  2. شکل خلاصه که از نمادگذاری [ElementType] استفاده می‌کند.
  3. استنباط نوع (Type inference).

می‌توان از شکل کامل به صورت زیر برای اعلان یک آرایه استفاده کرد:

var arrayOfInts: Array<Int> = [1، 2، 3، 4، 5، 6]

در این بخش ما یک آرایه به نام arrayOfInts را اعلان و مقداردهی اولیه کرده‌ایم که شامل نوع Int است و عنصر اول آرایه برابر با 1 و عنصر آخر 6 است. ما می‌توانیم از اندیس‌گذاری آرایه برای دسترسی به هر یک از عناصر آن استفاده کنیم. به خاطر داشته باشید که اندیس آرایه‌ها در سوئیفت از صفر آغاز می‌شود و عنصر آخر آرایه فوق در اندیس 5 قرار دارد:

arrayOfInts[5]

برای اعلان یک آرایه با استفاده از نمادگذاری خلاصه به صورت زیر عمل می‌کنیم:

var arrayOfInts: [Int] = [1، 2، 3، 4، 5، 6]

در نهایت برای اعلان یک آرایه با استفاده از استنباط نوع باید به صورت زیر عمل کنیم:

var arrayOfInts = [1، 2، 3، 4، 5، 6]

استنباط نوع در بخش کامپایلر سوئیفت اجرا می‌شود و نوع عناصر بر مبنای مقدار ارائه شده در زمان کامپایل تعیین می‌شود.

در سوئیفت نمادگذاری خلاصه نه‌تنها روشی ترجیحی برای اعلان یک آرایه محسوب می‌شود؛ بلکه از سوی اپل نیز توصیه می‌شود. استنباط نوع با این که در عمل جواب می‌دهد؛ اما با ریسک همراه است، چون سوئیفت در برخی مواد نمی‌تواند نوع صحیح مقدارها را تعیین کند. برای مثال در کد زیر:

var arrayOfFloats = [1.1، 1.2، 1.3، 1.4]

با این که قصد برنامه‌نویس اعلان و مقداردهی آرایه‌ای از نوع Float بوده است؛ اما استنباط نوع سوئیفت یک آرایه arrayOfFloats به صورت Double را اعلان و مقداردهی اولیه می‌کند.

مزیت دیگر «فرم خلاصه» نسبت به «استنباط نوع» این است که باعث می‌شود کدمان خوانایی بیشتری داشته باشد. اگر بخواهید آرایه‌ای خالی روی یک کلاس اعلان کنید، دانستن این که دقیقاً چه چیزی قرار بوده ذخیره شود دشوار خواهد بود. با این حال استفاده از اعلان و مقداردهی خلاصه آرایه کاملاً واضح خواهد بود.

بازیابی عناصر از یک آرایه

روش‌های مختلفی برای بازیابی یک عنصر از آرایه وجود دارد. اگر می‌خواهید تنها یک عنصر را بازیابی کنید و اندیس آن عنصر را می‌دانید می‌توانید از نمادگذاری زیرنویس استفاده کنید:

let arrayOfInts: [Int] = [1، 2، 3، 4]

let secondElementOfArray = arrayOfInts[1]

نمادگذاری فوق مقدار 2 را به دست می‌دهد. اگر می‌خواهید روی مقادیری در آرایه حلقه‌ای تعریف کنید، نمادگذاری زیرنویس کافی نخواهد بود و باید از ساختار for…in استفاده کنید:

let arrayOfInts: [Int] = [1، 2، 3، 4]

for anInt in arrayOfInts {

print(“Now printing: \(anInt)”)

}

کد فوق هر عنصر آرایه را یک به یک نمایش می‌دهد تا این که همه آن‌ها نمایش یابند. همچنین می‌توانید از مشخصات first و last کلاس آرایه برای دریافت دسترسی امن به ترتیب به عناصر اول و آخر آرایه استفاده کنید. این مشخصات در صورتی که آرایه خالی باشد مقدار تهی (nil) بازمی‌گردانند. برای نمونه:

let arrayOfInts: [Int] = [1، 2، 3، 4]

let firstInt: Int? = arraysOfInts.first

let lastInt: Int? = arraysOfInts.last

دو خط کد فوق به ترتیب مقادیر 1 و 4 را بازمی‌گردانند. دقت کنید که نوع firstInt و lastInt به صورت Int نیستند. آن‌ها از نوع Optional هستند، یعنی می‌توانند مقدار Int یا مقدار nil داشته باشند.

افزودن عناصر به یک آرایه

برای افزودن یک عنصر به آرایه بسته به این که بخواهید عنصر به کجای آرایه اضافه شود، راه‌های مختلفی وجود خواهد داشت. برای افزودن عناصر منفرد به انتهای آرایه می‌توان از متد (:_)append استفاده کرد:

var arrayOfInts: [Int] = [1، 2، 3، 4، 5]

arrayOfInts.append(6)

// arrayOfInts === [1، 2، 3، 4، 5، 6]

برای افزودن عناصر چندگانه به یک آرایه می‌توان آرایه یا دنباله دیگری را از هر نوع به متد (:append(contentsOf ارسال کرد. برای نمونه فرض کنید می‌خواهیم دو آرایه مانند زیر تعریف کنیم:

var firstArray: [Int] = [1، 2، 3]

var secondArray: [Int] = [4، 5، 6]

اکنون ببینیم که در حالت‌های مختلف چه اتفاقی رخ می‌دهد:

حالت 1:

firstArray.append(contentsOf: secondArray)

// firstArray === [1، 2، 3، 4، 5، 6]

حالت 2:

secondArray.append(contentsOf: firstArray)

// secondArray === [4، 5، 6، 1، 2، 3]

شما می‌توانید عناصر منفردی را با استفاده از متد (:insert(_:at در هر موقعیت آرایه اضافه کنید:

var arrayOfInts: [Int] = [1، 2، 3، 4، 5]

arrayOfInts.insert(6، at: 3)

// arrayOfInts === [1، 2، 3، 6، 4، 5]

در نهایت برای افزودن چند عنصر جدید در میانه آرایه می‌توانید از متد (:insert(contentsOf:at استفاده کنید:

var firstArray: [Int] = [1، 2، 3]

var secondArray: [Int] = [4، 5، 6]

firstArray.insert(contentsOf: secondArray، at: 2)

// firstArray === [1، 2، 4، 5، 6، 3]

حذف عناصر از یک آرایه

همانند روش افزودن عناصر، بسته به این که عنصر حذفی در انتهای آرایه باشد یا در ابتدا یا میانه آن قرار داشته باشد، می‌توان با استفاده از چندین روش اقدام به حذف عناصر از یک آرایه نمود.

برای حذف آخرین عنصر از یک آرایه می‌توان از متد ()removeLast استفاده کرد:

var arrayOfInts: [Int] = [1، 2، 3، 4، 5]

arrayOfInts.removeLast()

// arrayOfInts === [1، 2، 3، 4]

برای حذف عنصری از میانه آرایه می‌توان از متد (:remove(at استفاده کرد:

var arrayOfInts: [Int] = [1، 2، 3، 4، 5]

arrayOfInts.remove(at: 3)

// arrayOfInts === [1، 2، 3، 5]

arrayOfInts.remove(at: 0)

// arrayOfInts === [2، 3، 5]

برای حذف بازه‌ای از عناصر از یک آرایه می‌توان از متد (:_)removeSubrange استفاده کرد:

var arrayOfInts: [Int] = [1، 2، 3، 4، 5، 6]

arrayOfInts.removeSubrange(1..<4)

// arrayOfInts === [1، 5، 6]

در نهایت برای حذف همه عناصر از یک آرایه می‌توان از متد ()removeAll استفاده کند.

آرایه‌ها در زبان