PDA

View Full Version : سوال: مقدار دهی اولیه به آرایه



habibb
جمعه 06 بهمن 1391, 23:43 عصر
می خواهم یک آرایه تعریف کنم و بدون استفاده از حلقه for
n تا عدد از یک نوع رقم خاص بریزم توی خانه های آرایه مثلا 100 تا 6 یا 1000 تا 2
توی سی پلاس پلاس یادم هست که می شد هنگام تعریف آرایه داخل}{عدد مربوطه را نوشت .
حالا توی سی شارپ چه کار کنم ؟
راستی همان طور که می دانید اگر آرایه را مقدار دهی نکنید خود کامپایلر به صورت پیش فرض خانه های آرایه رو با صفر پر می کنه ؟ آیا می تونیم مقدار پیش فرض کامپایلر که صفر است رو
تغییر بدیم به 2 یا هر عدد دیگری ؟

mehdi.mousavi
شنبه 07 بهمن 1391, 07:44 صبح
سلام.
برای اینکار می تونید از LINQ استفاده کنید (البته Loop ارجحیت داره، چون سریعتره) اما در کل، Syntax خاصی برای اینکار در C# وجود نداره:

int[] numbers = Enumerable.Repeat<int>(6, 100).ToArray();

کد فوق، 100 تا عدد 6 رو در آرایه مورد نظر قرار میده.

موفق باشید.

habibb
سه شنبه 27 فروردین 1392, 17:51 عصر
از یک نفر راجب این موضوع پرسیدم گفت 3 روش داره !
حالا چند ساعت پیش از یکی دیگه پرسیدم گفت با ArrayList هم میشه System.Collections
کسی می دونه چطور میشه با ArrayList این کار رو کرد:متفکر:

tooraj_azizi_1035
سه شنبه 27 فروردین 1392, 17:58 عصر
سلام.
برای اینکار می تونید از LINQ استفاده کنید (البته Loop ارجحیت داره، چون سریعتره)
موفق باشید.
شما چرا میگید حلقه سریعتره؟

mehdi.mousavi
چهارشنبه 28 فروردین 1392, 14:28 عصر
شما چرا میگید حلقه سریعتره؟

سلام.
لطفا به Diagram زیر دقت کنید:

102968

من دو Function رو به دو صورت (یکی با استفاده از حلقه و دیگری با استفاده از روشی که در فوق به اون اشاره کردم، البته جای ToArray از ToList استفاده کردم، اما این مساله اهمیتی نداره ...) پیاده سازی کردم و سپس با Analyzer مدت زمان سپری شده در هر یک رو بدست آوردم. همونطوریکه مشاهده می کنید، استفاده از Loop بسیار سریعتر هستش. اما دلیلش چیه؟ متود های ToList، ToArray و ... بر اساس تعداد داده های ورودی در هر iterate باید اطمینان حاصل کنن که Array یا List ای به اندازه حافظه مورد نیاز وجود داره. در پیاده سازی فعلی، تعداد capacity ی پیش فرض 4 انتخاب شده. وقتی شما عنصر پنجم رو به لیست اضافه کنید، List باید Resize بشه... تعداد عناصر آرایه جدید 4 * 2 انتخاب میشه، یعنی این بار تا 8 عنصر رو میتونه لیست نگهداری کنه. وقتی عنصر 9 ام رو اضافه کنید، تعداد عتاصر لیست جدید بطور خودکار 8 * 2 یعنی 16 درنظر گرفته میشه و ... حالا در هر بار Resize شدن، متود Array.Copy فراخوانی میشه تا مقادیر رو در آرایه جدیدی قرار بده... حالا تصور کنید این عمل برای میلیونها رکورد تکرار بشه. نتیجه اش میشه Diagram فوق (تازه اگر هزینه بر بودن فراخوانی توابع رو نادیده بگیریم).

موفق باشید.

mehdi.mousavi
چهارشنبه 28 فروردین 1392, 14:44 عصر
از یک نفر راجب این موضوع پرسیدم گفت 3 روش داره ! حالا چند ساعت پیش از یکی دیگه پرسیدم گفت با ArrayList هم میشه System.Collections کسی می دونه چطور میشه با ArrayList این کار رو کرد:متفکر:

سلام. :)
با استفاده از ArrayList می تونید بدین شکل عمل کنید:

ArrayList result = ArrayList.Repeat(6, 100);

اما این دیگه فاجعه محسوب میشه... اینجا عمل Boxing/Unboxing (http://barnamenevis.org/showthread.php?315769-%D8%AA%D9%88%D9%84%DB%8C%D8%AF-%DB%8C%DA%A9-%D8%A2%D8%B1%D8%A7%DB%8C%D9%87-%D8%A8%D8%A7-%D8%AA%D8%B9%D8%AF%D8%A7%D8%AF-%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D9%86%D8%A7-%D9%85%D8%AD%D8%AF%D9%88%D8%AF&p=1385942&viewfull=1#post1385942) هم اتفاق می افته.

موفق باشید.

FastCode
چهارشنبه 28 فروردین 1392, 17:13 عصر
البته فکر میکنم این سریعتر از همه باشه.(64-bit) و Length باید زوج باشه

unsafe static int[] CreateIntArray (int Length, int InitialValue)
{
int[] Numbers = new int[Length];
Length >>= 1;
long lInitialValue = InitialValue;
lInitialValue |= lInitialValue << 32;
fixed (int * iNumbers = &Numbers[0]) {
long* lNumbers = (long*)iNumbers;
for (int counter = 0; counter != Length; counter++)
lNumbers [counter] = lInitialValue;
}
return Numbers;
}
البته فکر میکنم تا ۳ ۴ درصد سریعتر هم بشه ولی دیگه ارزش نداره.چون حجم کدش خیلی زیاد میشه.
البته اگر فقط از CLR استفاده نکنید خیلی کارهای دیگه هم میشه کرد.