কোনও স্ট্রিংয়ের তালিকা থেকে (স্ট্রিংয়ের) উপাদান রয়েছে কিনা তা পরীক্ষা করুন


155

নিম্নলিখিত কোড ব্লকের জন্য:

For I = 0 To listOfStrings.Count - 1
    If myString.Contains(lstOfStrings.Item(I)) Then
        Return True
    End If
Next
Return False

আউটপুটটি হ'ল:

মামলা 1:

myString: C:\Files\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: True

কেস 2:

myString: C:\Files3\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: False

তালিকায় (listOfStrings) বেশ কয়েকটি আইটেম থাকতে পারে (সর্বনিম্ন 20) এবং এটি কয়েক হাজার স্ট্রিং (মাই স্ট্রিংয়ের মতো) এর বিরুদ্ধে চেক করতে হবে।

এই কোডটি লেখার জন্য আরও ভাল (আরও দক্ষ) উপায় আছে?

উত্তর:


359

লিনকিউ সহ, এবং সি # ব্যবহার করে (আজকাল আমি ভিবি খুব বেশি জানি না):

bool b = listOfStrings.Any(s=>myString.Contains(s));

বা (খাটো এবং আরও দক্ষ, তবে তর্কাত্মকভাবে কম পরিষ্কার):

bool b = listOfStrings.Any(myString.Contains);

আপনি যদি সাম্যটি পরীক্ষা করে দেখেন তবে এটি HashSetইত্যাদির দিকে নজর দেওয়া উচিত তবে এটিকে আংশিক মিলগুলি সাহায্য করবে না যতক্ষণ না আপনি এটিকে টুকরো টুকরো করে ভাগ করেন এবং জটিলতার অর্ডার না যোগ করেন।


আপডেট: আপনি যদি সত্যিই "স্টার্টস উইথ" বোঝাতে চান তবে আপনি তালিকাটি বাছাই করতে এবং এটিকে একটি অ্যারেতে রাখতে পারেন; তারপরে Array.BinarySearchপ্রতিটি আইটেম সন্ধানের জন্য ব্যবহার করুন - এটি কোনও সম্পূর্ণ বা আংশিক মিল কিনা তা দেখার জন্য লুক করে দেখুন।


1
এর পরিবর্তে আমি তার উদাহরণগুলির উপর ভিত্তি করে স্টার্টসইথ ব্যবহার করব।
tvanfosson

@ ট্যানফসন - উদাহরণগুলি সম্পূর্ণরূপে অন্তর্ভুক্ত কিনা তার উপর এটি নির্ভর করে, তবে হ্যাঁ, আমি সম্মত হই। অবশ্যই পরিবর্তন করা সহজ।
মার্ক গ্র্যাভেল

অ্যালগোরিদমিক স্তরে এই কোডটি আরও কতটা কার্যকর? "যে কোনও" এর লুপগুলি দ্রুততর হয় তবে এটি সংক্ষিপ্ত এবং দ্রুত, তবে আপনি যে সমস্যাটি অনেক বার হুবহু মিলিয়ে দেখতে পারেন তা একই।
টর্স্টেন মেরেক

আপনি যদি কোনও সেট ব্যবহার করছেন তবে আপনি একটি কাস্টম তুলক সেটআপ করতে পারেন।
ফরটিআরুনার

অনুশীলনে কোনও পরিমাপযোগ্য পার্থক্য দ্বারা দ্বিতীয়টি আসলে বেশি দক্ষ নয়।
আইসিআর 16

7

আপনি যখন আপনার স্ট্রিংগুলি তৈরি করেন তখন এটি এমন হওয়া উচিত

bool inact = new string[] { "SUSPENDARE", "DIZOLVARE" }.Any(s=>stare.Contains(s));

5

আগের অনুরূপ প্রশ্ন " তুলনামূলক বড় তালিকার বিপরীতে বিদ্যমান স্ট্রিংয়ের পরীক্ষার সেরা উপায় " থেকে বেশ কয়েকটি পরামর্শ ছিল ।

আপনার প্রয়োজনের জন্য রেজেক্স যথেষ্ট হতে পারে। এই অভিব্যক্তিটি সমস্ত প্রার্থীর সাবস্ট্রিংগুলির একটি সংক্ষেপণ হবে, যার মধ্যে একটি " |" বা অপারেটর রয়েছে। অবশ্যই, ভাবটি তৈরি করার সময় আপনাকে অপ্রকাশিত অক্ষরগুলি, বা জটিলতা বা আকারের সীমাবদ্ধতার কারণে এটি সংকলন করতে ব্যর্থ হতে হবে।

এটি করার আরেকটি উপায় হ'ল সমস্ত প্রার্থীর সাবস্ট্রিংগুলিকে উপস্থাপন করার জন্য একটি ত্রি ডাটা স্ট্রাকচার তৈরি করা (এটি কিছুটা ডুপ্লিকেট করে রেজেক্স ম্যাথার কী করছে)। পরীক্ষার স্ট্রিংয়ের প্রতিটি চরিত্রের সাথে পদক্ষেপ নেওয়ার সাথে সাথে আপনি ট্রাইয়ের মূলটিতে একটি নতুন পয়েন্টার তৈরি করতে এবং বিদ্যমান পয়েন্টারগুলিকে যথাযথ সন্তানের দিকে (যদি কোনও হয়) আগমন করবেন। কোনও পয়েন্টার কোনও পাতায় পৌঁছালে আপনি একটি ম্যাচ পান।


5

আমি মার্কের উত্তরটি পছন্দ করেছি, তবে CaSe InSenSiTiVe হওয়ার জন্য কনটেন্টগুলির সাথে ম্যাচিংয়ের দরকার ছিল।

এই সমাধান ছিল:

bool b = listOfStrings.Any(s => myString.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0))

এটি> -1 হওয়া উচিত নয়?
সিআরপিড হয়েছে

1
@ সিশারপডগুলি> -1 (বিয়োগ 1-এর বেশি) এবং> = 0 (শূন্যের বেশি বা সমান) হিসাবে একই জিনিস নয়।
WHIsRich

2

আপনার নিদর্শনগুলির উপর ভিত্তি করে একটি উন্নতি হ'ল এটির পরিবর্তে স্টার্টসইথ ব্যবহারে পরিবর্তন করা। স্টার্টসগুলি প্রতিটি স্ট্রিংয়ের মধ্যে কেবল পুনরাবৃত্তি করা দরকার যতক্ষণ না এটি অনুসন্ধান করতে প্রতিটি অক্ষর অবস্থানে অনুসন্ধানটি পুনরায় আরম্ভ করার পরিবর্তে প্রথম মিল না পেয়ে এটি খুঁজে পায় one

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

string[] pathComponents = myString.Split( Path.DirectorySeparatorChar );
string startPath = pathComponents[0] + Path.DirectorySeparatorChar;

return listOfStrings.Contains( startPath );

সম্পাদনা : হ্যাশসেট ধারণাটি ব্যবহার করা এটি আরও দ্রুত হবে @ মার্ক গ্র্যাভেল উল্লেখ করেছেন যেহেতু আপনি পরিবর্তন Containsকরতে পারেন ContainsKeyএবং অনুসন্ধানটি ও (এন) এর পরিবর্তে ও (1) হবে। আপনাকে অবশ্যই নিশ্চিত করতে হবে যে পথগুলি ঠিক মিলেছে। মনে রাখবেন যে এটি @ মার্ক গ্র্যাভেলের মতো সাধারণ সমাধান নয় তবে এটি আপনার উদাহরণ অনুসারে তৈরি।

সি # উদাহরণের জন্য দুঃখিত। আমার কাছে ভিবিতে অনুবাদ করার মতো পর্যাপ্ত কফি নেই।


পুনরায় শুরু; সম্ভবত প্রাক সাজান এবং বাইনারি অনুসন্ধান ব্যবহার? এটি আবার দ্রুত হতে পারে।
মার্ক গ্র্যাভেল

2

পুরানো প্রশ্ন। তবে যেহেতু VB.NETআসল প্রয়োজন ছিল। গৃহীত উত্তরের একই মানগুলি ব্যবহার করে:

listOfStrings.Any(Function(s) myString.Contains(s))

1

আপনি কি গতি পরীক্ষা করেছেন?

অর্থাৎ আপনি কি ডেটার একটি নমুনা সেট তৈরি করেছেন এবং এটি প্রোফাইল করেছেন? আপনি যতটা ভাবেন তত খারাপ নাও হতে পারে।

এটি এমন কিছুও হতে পারে যা আপনি আলাদা থ্রেডে ছড়িয়ে দিতে পারেন এবং গতির মায়া দিতে পারেন!


0

গতি যদি গুরুতর হয় তবে আপনি প্যাটার্নের সেটগুলির জন্য আহো-করাসিক অ্যালগরিদম সন্ধান করতে পারেন ।

এটি ব্যর্থতার লিঙ্কগুলির সাথে একটি ট্রাই , অর্থাত্ জটিলতা হ'ল হে (এন + এম + কে), যেখানে এন ইনপুট পাঠ্যের দৈর্ঘ্য, এম নিদর্শনগুলির সংখ্যার দৈর্ঘ্য এবং কে মিলগুলির সংখ্যা। প্রথম ম্যাচটি খুঁজে পাওয়ার পরে আপনাকে শেষ করতে কেবল অ্যালগরিদমটি সংশোধন করতে হবে।



0

Containsপদ্ধতির অপূর্ণতা হ'ল এটি তুলনা প্রকারটি নির্দিষ্ট করতে দেয় না যা স্ট্রিংগুলির সাথে তুলনা করার সময় প্রায়শই গুরুত্বপূর্ণ। এটি সর্বদা সংস্কৃতি সংবেদনশীল এবং কেস-সংবেদনশীল। সুতরাং আমি মনে করি WHOSRich এর উত্তর মূল্যবান, আমি কেবল একটি সহজ বিকল্প দেখাতে চাই:

listOfStrings.Any(s => s.Equals(myString, StringComparison.OrdinalIgnoreCase))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.