সি # তে পূর্ণসংখ্যার অ্যারের যোগফল কীভাবে করবেন


108

অ্যারে দিয়ে পুনরুক্তি করার চেয়ে আরও ভাল আর কি উপায় আছে?

int[] arr = new int[] { 1, 2, 3 };
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
    sum += arr[i];
}

শোধন:

উন্নত প্রাথমিক অর্থ ক্লিনার কোড তবে কর্মক্ষমতা উন্নতির ইঙ্গিতগুলিও স্বাগত। (ইতিমধ্যে উল্লিখিত: বড় অ্যারেগুলি বিভক্ত করা)।


আমি হত্যাকারী পারফরম্যান্সের উন্নতির জন্য এটির মতো খুঁজছিলাম না - আমি কেবলই ভাবছিলাম যে যদি এই ধরণের সিনট্যাকটিক চিনি ইতিমধ্যে পাওয়া না যায়: "সেখানে স্ট্রিং রয়েছে। জয়ন - ইনট সম্পর্কে কি হ্যাক?"। "


2
কীভাবে ভাল? দ্রুত? কম লিখিত কোড?
ফ্রেড্রিক

উত্তর:


186

প্রদত্ত যে আপনি .NET 3.5 (বা আরও নতুন) এবং লিনকিউ ব্যবহার করতে পারেন, চেষ্টা করুন

int sum = arr.Sum();

10
পরিচয় ল্যাম্বদা প্রয়োজনীয় নয়। দলে নতুন লোকটিকে বিভ্রান্ত করা বাদে।

12
এটি লক্ষণীয় যে System.OverflowExceptionফলাফলটি যদি আপনি স্বাক্ষরিত 32 বিট পূর্ণসংখ্যার (যেমন (2 ^ 31) -1 বা ইংরেজিতে 2.1 বিলিয়ন ডলার) ফিট করতে পারেন তবে তার চেয়ে বেশি ফলস্বরূপ এটি একটি ত্রুটি বাড়িয়ে তুলবে।
ক্রিসপ্রসার

2
int sum = arr.AsParallel().Sum();একটি দ্রুত সংস্করণ যা সিপিইউয়ের একাধিক কোর ব্যবহার করে। এড়ানোর জন্য System.OverflowExceptionআপনি ব্যবহার করতে পারেন long sum = arr.AsParallel().Sum(x => (long)x);এড়াতে ওভারফ্লো ব্যতিক্রম আরও দ্রুত সংস্করণ জন্য এবং সমর্থন সব পূর্ণসংখ্যা ডেটার প্রকার এবং ব্যবহারের তথ্য সমান্তরাল SIMD / SSE নির্দেশাবলী, HPCsharp nuget প্যাকেজ কটাক্ষপাত করা
DragonSpit

66

হ্যা এখানে. নেট 3.5 সাথে:

int sum = arr.Sum();
Console.WriteLine(sum);

যদি আপনি .NET 3.5 ব্যবহার না করেন তবে আপনি এটি করতে পারেন:

int sum = 0;
Array.ForEach(arr, delegate(int i) { sum += i; });
Console.WriteLine(sum);

2
কেন এইরকম কনভোল্টেড প্রাক 3.5 সংস্করণ? foreachলুপ সি # এর সব সংস্করণ পাওয়া যায়।
জার্ন শো-রোড

2
@ জার্ন: ওপি আরও সংক্ষিপ্ত পদ্ধতির জন্য বলেছে। একটি foreachকেবল অন্যের জন্য কোডের এক লাইনকে প্রতিস্থাপন করে এবং সংক্ষিপ্ত হয় না। এ ছাড়া একটি foreachপুরোপুরি ভাল এবং আরও পঠনযোগ্য।
আহমাদ মার্জ

2
পয়েন্ট নেওয়া হয়েছে। তবুও, আপনার নমুনার তুলনায় foreach (int i in arr) sum += i;
নীচেরগুলি


5

এটি কীভাবে আপনি আরও ভাল সংজ্ঞা দেন তার উপর নির্ভর করে। আপনি যদি কোডটি আরও পরিষ্কার দেখতে চান তবে আপনি অন্যান্য উত্তরে উল্লিখিত হিসাবে সুম () ব্যবহার করতে পারেন। আপনি যদি অপারেশনটি দ্রুত চালিত করতে চান এবং আপনার কাছে একটি বড় অ্যারে রয়েছে, আপনি এটিকে উপ-যোগে ভাগ করে সমান্তরাল করতে পারেন এবং তারপরে ফলাফলগুলি যোগ করতে পারেন।


+1 পারফরম্যান্স উন্নতির জন্য খুব ভাল পয়েন্ট তবে সত্যই আমার প্রাথমিক ইচ্ছাটি ছিল পুনরাবৃত্তিটি থেকে মুক্তি পাওয়া।
ফিল্বুর্ট

(কেউ

@ উইল: ডুড - আমি কোড জাদুটি না লিখলে আমার বিশ্বাস আশা করবেন না ;-)
ফিলবার্ট

3
আমি সন্দেহ করি যে এরকম সমান্তরাল অপ্টিমাইজেশানটি বোঝার আগে এটি খুব বড় অ্যারে হতে হবে।
ইয়ান মেরার

হ্যাঁ, কখন থেকে লুপের জন্য খারাপ অভ্যাস হয়ে গেল?
এড এস।

3

Aggregate()এক্সটেনশন পদ্ধতিটি ব্যবহার করার জন্য এটি বিকল্প ।

var sum = arr.Aggregate((temp, x) => temp+x);

1
সুম যেখানে কাজ করে না সেখানে এটি কাজ করে বলে মনে হচ্ছে। এটি কোনও কারণে ইউন্টের অ্যারেতে কাজ করবে না তবে সমষ্টিগত হবে।
জন আর্নেস্ট

2

আপনি যদি লিনিকিউ পছন্দ না করেন তবে সূচকের বাইরে এড়ানোর জন্য ফোরচ লুপ ব্যবহার করা ভাল।

int[] arr = new int[] { 1, 2, 3 };
int sum = 0;
foreach (var item in arr)
{
   sum += item;
}

2

অত্যন্ত বড় অ্যারেগুলির জন্য এটি মেশিনের একাধিক প্রসেসর / কোর ব্যবহার করে গণনা সম্পাদন করতে পারে।

long sum = 0;
var options = new ParallelOptions()
    { MaxDegreeOfParallelism = Environment.ProcessorCount };
Parallel.ForEach(Partitioner.Create(0, arr.Length), options, range =>
{
    long localSum = 0;
    for (int i = range.Item1; i < range.Item2; i++)
    {
        localSum += arr[i];
    }
    Interlocked.Add(ref sum, localSum);
});

2

উপরের লুপ সমাধানগুলির জন্য একটি সমস্যা হ'ল সমস্ত ধনাত্মক মান সহ নিম্নলিখিত ইনপুট অ্যারের জন্য, যোগফলটি নেতিবাচক:

int[] arr = new int[] { Int32.MaxValue, 1 };
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
    sum += arr[i];
}
Console.WriteLine(sum);

যোগফলটি -2147483648, কারণ ইতিবাচক ফলাফলটি ইনট ডাটা টাইপের জন্য খুব বড় এবং নেতিবাচক মান হিসাবে ওভারফ্লো হয়।

একই ইনপুট অ্যারের জন্য অ্যারেরসাম () পরামর্শগুলি একটি ওভারফ্লো ব্যতিক্রম নিক্ষেপ করে cause

আরও শক্তিশালী সমাধান হ'ল বৃহত্তর ডেটা ধরণের ব্যবহার করা যেমন "লং" এই ক্ষেত্রে "যোগফল" এর জন্য:

int[] arr = new int[] { Int32.MaxValue, 1 };
long sum = 0;
for (int i = 0; i < arr.Length; i++)
{
    sum += arr[i];
}

সংক্ষিপ্ত এবং এসবিট হিসাবে অন্যান্য পূর্ণসংখ্যার ডেটা সংক্রমণের জন্য একই উন্নতি কাজ করে। স্বাক্ষরযুক্ত পূর্ণসংখ্যার ডেটা যেমন ইউন্ট, ইউএসোর্ট এবং বাইটের অ্যারেগুলির জন্য, যোগফলের জন্য একটি স্বাক্ষরযুক্ত দীর্ঘ (উলং) ব্যবহার করে ওভারফ্লো ব্যতিক্রম এড়ানো যায়।

লুপ সলিউশনটির জন্য লিনাকের চেয়ে বহুগুণ দ্রুত umসুম ()

আরও দ্রুত চালানোর জন্য, এইচপিস্যাশার্প নুগেট প্যাকেজটি এই সমস্ত .সাম () সংস্করণগুলির পাশাপাশি সিমডি / এসএসই সংস্করণ এবং মাল্টি-কোর সমান্তরালগুলি প্রয়োগ করে, বহু গুণ দ্রুত পারফরম্যান্সের জন্য।


ভালো বুদ্ধি. এবং, স্বাক্ষরবিহীন পূর্ণসংখ্যার অ্যারের জন্য উলং যোগ = arr.Sum (x => (উলং) এক্স) করতে সক্ষম হওয়াই ভাল লাগবে; তবে, দুঃখের বিষয়, লিনক .সুম () স্বাক্ষরবিহীন পূর্ণসংখ্যার ডেটা ধরণের সমর্থন করে না। স্বাক্ষরযুক্ত সমষ্টি প্রয়োজন হলে, এইচপিসারশ্প নুগেট প্যাকেজ সমস্ত স্বাক্ষরযুক্ত ডেটা ধরণের জন্য এটি সমর্থন করে।
ড্রাগনস্পিট

একটি অবদানকারী একটি দুর্দান্ত ধারণা প্রত্যাহার করেছিলেন long sum = arr.Sum(x => (long)x);যা লিনক ব্যবহার করে সি # তে দুর্দান্তভাবে কাজ করে। এটি সমস্ত স্বাক্ষরিত পূর্ণসংখ্যার ডেটা টাইপগুলির সংমিশ্রণের জন্য সম্পূর্ণ নির্ভুলতা সরবরাহ করে: এসবিটি, শর্ট এবং ইনট। এটি একটি ওভারফ্লো ব্যতিক্রম ছোঁড়া এড়াতে এবং সুন্দরভাবে কমপ্যাক্ট। এটি উপরের লুপের মতো উচ্চ কার্যকারিতা নয়, তবে সব ক্ষেত্রেই পারফরম্যান্সের প্রয়োজন হয় না।
ড্রাগনস্পটিট

0

ফরচ ব্যবহার করা সংক্ষিপ্ত কোড হবে, তবে সম্ভবত জেআইটি অপ্টিমাইজেশনের জন্য লুপ নিয়ন্ত্রণকারী এক্সপ্রেশনটিতে দৈর্ঘ্যের তুলনা স্বীকৃতি দেওয়ার পরে রানটাইমের সময় ঠিক একই ধাপগুলি করবে।


0

আমার অ্যাপগুলির একটিতে আমি ব্যবহার করেছি:

public class ClassBlock
{
    public int[] p;
    public int Sum
    {
        get { int s = 0;  Array.ForEach(p, delegate (int i) { s += i; }); return s; }
    }
}

এটি .Aggregate()এক্সটেনশন পদ্ধতিটি ব্যবহার করার মতো ।
জন আলেক্সিউ

-1

থিওডর জৌলিয়াসের দুর্দান্ত মাল্টি-কোর সমান্তরাল সম্পর্কে উন্নতি ach

    public static ulong SumToUlongPar(this uint[] arrayToSum, int startIndex, int length, int degreeOfParallelism = 0)
    {
        var concurrentSums = new ConcurrentBag<ulong>();

        int maxDegreeOfPar = degreeOfParallelism <= 0 ? Environment.ProcessorCount : degreeOfParallelism;
        var options = new ParallelOptions() { MaxDegreeOfParallelism = maxDegreeOfPar };

        Parallel.ForEach(Partitioner.Create(startIndex, startIndex + length), options, range =>
        {
            ulong localSum = 0;
            for (int i = range.Item1; i < range.Item2; i++)
                localSum += arrayToSum[i];
            concurrentSums.Add(localSum);
        });

        ulong sum = 0;
        var sumsArray = concurrentSums.ToArray();
        for (int i = 0; i < sumsArray.Length; i++)
            sum += sumsArray[i];

        return sum;
    }

যা স্বাক্ষরবিহীন পূর্ণসংখ্যার ডেটা ধরণের জন্য কাজ করে, যেহেতু সি # কেবল ইন্টারলকডকে সমর্থন করে int উপরের প্রয়োগটি সিপিইউর একাধিক কোর ব্যবহার করে সমান্তরালে সমষ্টি করতে অন্যান্য পূর্ণসংখ্যার এবং ফ্লোটিং-পয়েন্ট ডেটা প্রকারকে সমর্থন করার জন্যও সহজেই সংশোধন করা যেতে পারে। এটি HPCsharp nuget প্যাকেজে ব্যবহৃত হয়।


-7

এই কোড ব্যবহার করে দেখুন:

using System;

namespace Array
{
    class Program
    {
        static void Main()
        {
            int[] number = new int[] {5, 5, 6, 7};

            int sum = 0;
            for (int i = 0; i <number.Length; i++)
            {
                sum += number[i];
            }
            Console.WriteLine(sum);
        }
    }
} 

ফলাফল হলো:

23


আপনার কোডটি সঠিক নয়, আপনাকে অবশ্যই কনসোলটি প্রতিস্থাপন করতে হবে rite রাইটলাইন (যোগফল); ফেরত যোগফল সহ; এবং এটি কাজ করবে
আবদেসামাদ জাদিদ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.