তালিকার সমস্ত মান পৃথক হলে পরীক্ষা করুন Test


90

আমার কাছে বাইটগুলির একটি ছোট তালিকা রয়েছে এবং আমি এটি পরীক্ষা করতে চাই যে সেগুলি সমস্ত ভিন্ন মান। উদাহরণস্বরূপ, আমার এটি রয়েছে:

List<byte> theList = new List<byte> { 1,4,3,6,1 };

সমস্ত মান পৃথক কিনা তা যাচাই করার সর্বোত্তম উপায় কী?


4
যেহেতু এটি একটি সাধারণ শ্রেণিকক্ষের প্রশ্ন, আমি একটি প্রশ্নের উত্তর দিয়ে দেব। এটি বাছাই করা থাকলে আপনি কী করবেন?
— ctrl-alt-delor

উত্তর:


168
bool isUnique = theList.Distinct().Count() == theList.Count();

শুধু কৌতূহলী: এর স্থান এবং সময়ের প্রয়োজনীয়তাগুলি কী?
— dtb

10
@ ডিটিবি ও (এন) সম্পর্কে হওয়া উচিত । অবশ্যই এটি একটি "ছোট তালিকা" হিসাবে বিবেচনা করে এটি প্রায় যে কোনও অ্যালগরিদমের সাথে বজ্রগতিযুক্ত হবে। IMO এটি পঠনযোগ্যতা এবং সংক্ষিপ্ততার উপর জিতেছে এবং গতি যেহেতু কোনও সমস্যা নয়, এটি এটিকে নিখুঁত করে তোলে।
— টিম এস

4
এটি যতটা দক্ষ তার চেয়ে বেশি দক্ষ
— Jodrell

74

এখানে আরও একটি পদ্ধতি যা Enumerable.Distinct+ এর চেয়ে বেশি দক্ষ Enumerable.Count(সিক্যুয়েন্সটি সংগ্রহের ধরণের না হলে আরও বেশি)। এটি এমন একটি ব্যবহার করে HashSet<T>যা সদৃশগুলি মুছে ফেলে, দর্শনগুলিতে খুব দক্ষ এবং একটি গণনা-সম্পত্তি রয়েছে:

var distinctBytes = new HashSet<byte>(theList);
bool allDifferent = distinctBytes.Count == theList.Count;

বা অন্য - আরও সূক্ষ্ম এবং দক্ষ - পদ্ধতির:

var diffChecker = new HashSet<byte>();
bool allDifferent = theList.All(diffChecker.Add);

HashSet<T>.Addfalseউপাদানটি যুক্ত করা যায়নি যদি ইতিমধ্যে এটি ইতিমধ্যে ছিল তবে ফিরে আসে HashSet। Enumerable.Allপ্রথম "মিথ্যা" থামে।


4
এত সহজ এবং সুস্পষ্ট, কেন আমি প্রথমে এটি সম্পর্কে চিন্তা করিনি :) আমি আমার এক দারুণ কোড দ্বারা উত্পাদিত 10 মিলিয়ন উপাদানগুলি সত্যই অনন্য বলে নিশ্চিত করার জন্য ইউনিট পরীক্ষায় এই ওয়ান-লাইনারটি ব্যবহার করেছি Assert.IsTrue(samples.Add(AwesomeClass.GetUnique()));। তারা ছিল এবং :) +1 টি আপনি টিম জন্য :)
— grapkulec

4
আমি এই প্রশ্নে আপনার উত্তর চেষ্টা করেছি কিন্তু এটা কাজ করছে না স্যার: stackoverflow.com/questions/34941162/...
— শিক্ষণ-Overthinker-বিভ্রান্ত

এটি হওয়া উচিত:bool allDifferent = theList.All(s => diffChecker.Add(s))
— মাইক নেলসন

4
না, দরকার নেই। এই ক্ষেত্রে আপনি সরাসরি প্রতিনিধিটি পাস করতে পারবেন
— টিম শ্মেলটার

4
@ অ্যান্ড্রে রিচেল্ট - আমি সবেমাত্র আপনার কোডটি খুলেছি এবং তৃতীয় দৃশ্যটি ( List.All(HashSet.Add)) প্রায় সমস্ত ক্ষেত্রে অন্য দুটি তুলনায় খুব দ্রুত বলে মনে হচ্ছে
— কাইল ডেলানি

6

ঠিক আছে, এখানে আমি স্ট্যান্ডার্ড। নেট ব্যবহারের কথা ভাবতে পারি এমন সবচেয়ে কার্যকর পদ্ধতি

using System;
using System.Collections.Generic;

public static class Extension
{
    public static bool HasDuplicate<T>(
        this IEnumerable<T> source,
        out T firstDuplicate)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        var checkBuffer = new HashSet<T>();
        foreach (var t in source)
        {
            if (checkBuffer.Add(t))
            {
                continue;
            }

            firstDuplicate = t;
            return true;
        }

        firstDuplicate = default(T);
        return false;
    }
}

মূলত, পুরো ক্রমটি দু'বার গণনার মূল বিষয়টি যদি আপনি করতে চান তবে প্রথম নকলটি সন্ধান করুন।

আমি একটি খালি এবং একক উপাদান ক্রম বিশেষ কেসিং দ্বারা এটি আরও অনুকূল করতে পারি তবে এটি পঠনযোগ্যতা / ন্যূনতম লাভের সাথে রক্ষণাবেক্ষণযোগ্যতা থেকে অবমূল্যায়ন করবে।


ডুপ্লিকেট ভ্যালু আউট রিটার্ন যোগ করা ভাল, বৈধতার জন্য বেশ কার্যকর
— প্যাক0

আমি এখানে 3 টি সমাধান সমাধান করেছি এবং এটি এই পৃষ্ঠায় সর্বাধিক দক্ষ। যদিও সেখানে কয়েকটি টাইপো (যেমন sequenceহওয়া উচিত source)। এগুলি স্থির হয়ে গেলে দুর্দান্ত কাজ করে
— মাইক নেলসন

@mikenelson, যে ভাল হওয়া উচিত
— Jodrell

4
পাঠযোগ্যতার জন্য, আমি মনে করি এটি if (!checkBuffer.Add(t)) { firstDuplicate = t; return true }লুপে থাকা উচিত ।
— টিয়া

2

Distinctব্যবহার করার অনুরূপ যুক্তি GroupBy:

var isUnique = theList.GroupBy(i => i).Count() == theList.Count;

আপনি যদি কোনও সম্পত্তির সাথে স্বতন্ত্রতা পরীক্ষা করতে চান theList.GroupBy(o => o.SomeProperty).Count() == theList.Count;তবে ডাস্টিনেক্ট () এটি অনুমতি দেয় না তবে এটি কার্যকর।
— Rev1.0

1

একটি এছাড়াও করতে পারেন: হ্যাশসেট ব্যবহার করুন

var uniqueIds = new HashSet<long>(originalList.Select(item => item.Id));

            if (uniqueIds.Count != originalList.Count)
            {
            }

0

অনেকগুলি সমাধান রয়েছে।

লিনকিউ ব্যবহারের সাথে "জুয়েরজেন ডি" এবং "টিম শেমলেটার" উল্লেখ করা সন্দেহজনক কোন সন্দেহ নেই।

তবে, যদি আপনি "জটিলতা" এবং গতি অর্জন করেন তবে সেরা সমাধানটি নিজের দ্বারা বাস্তবায়ন করা হবে implement সমাধানগুলির মধ্যে একটি হ'ল এন আকারের একটি অ্যারে তৈরি করা হবে (বাইটের জন্য এটি 256)। এবং অ্যারে লুপ করুন, এবং প্রতিটি পুনরাবৃত্তির সাথে মিলটি নম্বর সূচকটি পরীক্ষা করে দেখাবে যদি মানটি 1 হয় তবে এর অর্থ আমি ইতিমধ্যে অ্যারে সূচককে বাড়িয়েছি এবং তাই অ্যারে আলাদা নয় অন্যথায় আমি অ্যারে সেলটি বৃদ্ধি করব এবং চেকিং চালিয়ে যাব ।


4
আপনি 256 বিট = 32 বাইট = 8 পূর্ণসংখ্যার সাথে কিছুটা ভেক্টর ব্যবহার করতে পারেন। তবে আপনার বিগ ও = ও (এন) এখনও অন্য উত্তরে প্রস্তাবিত হাশেট ব্যবহার করার মতো হবে।
— ব্রোকেনগ্লাস 21 '45

এটি O (n) তাই সম্ভবত দ্রুত, (এটি পরীক্ষা করুন)। আপনি যেতে হিসাবে গণনা চেক বা শেষ দিকে দ্রুত হবে? আমি সন্দেহ করি যে শেষে খারাপের ক্ষেত্রে উন্নতি হবে তবে আপনি যেতে পারলে গড় এবং সেরা ক্ষেত্রে উন্নতি হতে পারে)। যদি কোনও সদৃশ না থাকে তবে এটি সবচেয়ে খারাপ ক্ষেত্রে পারফরম্যান্স। বড় ডেটা ধরণের জন্য এটি ভাল কাজ করবে না, একটি 16 বিট টাইপের জন্য আপনাকে k৪ কে গণনা, ভাল k৪ কে বিট (৮ কে বাইট) ব্যবহার করতে হবে তবে বড় কিছু হলেও মেমরির ব্যবহার নিরীহ হতে শুরু করবে। তবে আমি 8 বিট মানগুলির জন্য এই উত্তরটি পছন্দ করি।
— ctrl-alt-delor

4
@ তমুসজেয়েস আপনি যদি 4294967296 সম্ভাবনাগুলি সঞ্চয় করতে চান তবে আপনার 4 জিবি প্রয়োজন 42 এমবি নয় (বা আপনার মধ্যে 512 এমবি বিট মাস্কিং ব্যবহার করুন)
— টাইগ্রুয়ে

আমি কী ভাবছিলাম তা নিশ্চিত নয়। "সমস্ত 4294967296 সম্ভাব্যতা ধরে রাখার জন্য 42MB + মেমরির বরাদ্দ করুন simple একদিন এটি যোগ্যতা ধরে রাখতে পারে। আসলেই কোনও প্রাসঙ্গিক মন্তব্য নয়। হ্যাশেট সেরা হবে। যদি আপনি অত্যন্ত বড় অ্যারেগুলি নিয়ে কাজ করে থাকেন তবে আপনি অত্যন্ত বড় মেমরির প্রত্যাশা করেন। তবে এরকম অদ্ভুত প্রান্তের ক্ষেত্রে, সিআরসি অ্যালগরিদমের সাথে হারিস্টিক ভাল হবে। এটি একটি বহুবর্ষে মানচিত্র করুন। কাছে থাকলে মূল্যায়ন করুন। ধন্যবাদ @ টিগ্রো!
— তমুসজেরোয়েস

0

এবং অন্য সমাধান, যদি আপনি সদৃশ মানগুলি খুঁজতে চান।

var values = new [] { 9, 7, 2, 6, 7, 3, 8, 2 };

var sorted = values.ToList();
sorted.Sort();
for (var index = 1; index < sorted.Count; index++)
{
    var previous = sorted[index - 1];
    var current = sorted[index];
    if (current == previous)
        Console.WriteLine(string.Format("duplicated value: {0}", current));
}

আউটপুট:

duplicated value: 2
duplicated value: 7

http://rextester.com/SIDG48202


0

কোনও পরীক্ষামূলক (অ্যারে, তালিকা, ইত্যাদি) এর মতো অনন্য কিনা তা আমি পরীক্ষা করি:

var isUnique = someObjectsEnum.GroupBy(o => o.SomeProperty).Max(g => g.Count()) == 1;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.