আমি কীভাবে উদ্দেশ্য-সি-তে কোনও এনএসআরির বিপরীত করতে পারি?


356

আমার আমার বিপরীত দরকার NSArray

উদাহরণ হিসাবে:

[1,2,3,4,5] অবশ্যই হয়ে উঠবে: [5,4,3,2,1]

এই অর্জন করার সেরা উপায় কি?


1
এটি এটিকে দেখার মতোও রয়েছে : http://developer.apple.com/mac/library/docamentation/Cocoa/Concepual/ Collections / Articles / sortingFilteringArrays.html যা আপনাকে বিপরীত ক্রমে কীভাবে অ্যারে বাছাই করতে বলে (যা সাধারণত কী উদাহরণস্বরূপ, এনএসডিকোয়ারিয়ান # allKeys থেকে প্রাপ্ত একটি অ্যারে ব্যবহার করার ক্ষেত্রে আপনি করছেন, এবং আপনি আইফোন ইত্যাদির জন্য ইউআইটিবেবলের গোষ্ঠীকরণের জন্য বিপরীত তারিখ / আলফা ক্রমটি চান)।

উত্তর:


305

একটি অ্যারের বিপরীত অনুলিপি পেতে, ব্যবহার করে ড্যানিয়েলপুঙ্কাস সমাধান দেখুন reverseObjectEnumerator

পরিবর্তনীয় অ্যারেটি উল্টানোর জন্য আপনি নিম্নলিখিত কোডটি আপনার কোডে যুক্ত করতে পারেন:

@implementation NSMutableArray (Reverse)

- (void)reverse {
    if ([self count] <= 1)
        return;
    NSUInteger i = 0;
    NSUInteger j = [self count] - 1;
    while (i < j) {
        [self exchangeObjectAtIndex:i
                  withObjectAtIndex:j];

        i++;
        j--;
    }
}

@end

15
দ্রুত গণনার সম্পর্কে একটি খারাপ জিনিস হ'ল আমার মতো নতুন ছেলেরা রিভারসঅবজেক্ট-ইনমিটারের মতো শীতল জিনিসগুলি সম্পর্কে শিখেন না। এটি করার খুব সুন্দর উপায়।
ব্রেন্ট রয়েল-গর্ডন

4
সি ++ - পুনরাবৃত্তকারীগুলির আরও খারাপ সিনট্যাক্স রয়েছে বলে তারা কুশ্রী।
জর্জি স্কলি

4
অ্যারেটি ফেরত দেওয়ার আগে আপনার কপি করা উচিত নয়?
সিআইফিল্টার

12
@ জর্জি: আমি এই বিষয়ে আপনার সাথে একমত নই। যদি আমি এমন কোনও পদ্ধতি দেখি যা অপরিবর্তনীয় বস্তুকে ফেরত দেয় তবে আমি প্রত্যাশা করি যে এটি আসলে একটি অপরিবর্তনীয় বস্তুটি ফিরিয়ে দেবে। এটি একটি অপরিবর্তনীয় বস্তু ফিরে আসবে বলে মনে হচ্ছে তবে প্রকৃত প্রত্যাবর্তন একটি পরিবর্তনীয় জিনিস intoোকা একটি বিপজ্জনক অভ্যাস।
ক্রিস্টিন

3
ReverseObjectEnumerator allObjects প্রস্তাবনা সহায়ক যেহেতু এটি বিপরীত করে না চপল এরে, এমনকি যোগ করার mutableCopy সাহায্য করবে না যেহেতু এখনও মূল অ্যারের ভাবে পরিবর্তিত হয় না। অ্যাপল নথি যে অপরিবর্তনীয়তা রান সময় পরীক্ষা করা উচিত নয় , কিন্তু ফিরে আসা টাইপ উপর ভিত্তি করে ধরে নেওয়া উচিত, সুতরাং এই ক্ষেত্রে একটি NSMutableArray ফিরিয়ে দেওয়া পুরোপুরি সঠিক কোড।
পিটার এন লুইস

1287

আরও সহজ সমাধান রয়েছে, যদি আপনি অন্তর্নির্মিত reverseObjectEnumeratorপদ্ধতিটি NSArrayএবং এর allObjectsপদ্ধতিটি গ্রহণ করেন NSEnumerator:

NSArray* reversedArray = [[startArray reverseObjectEnumerator] allObjects];

allObjectsnextObjectযাতে এখনও ক্রমবিবর্তিত হয়নি এমন বস্তুগুলির সাথে একটি অ্যারে ফেরত হিসাবে নথিভুক্ত করা হয়েছে :

এই অ্যারেতে অঙ্কিত ক্রমের মধ্যে গণকের বাকী সমস্ত অবজেক্ট রয়েছে ।


6
এখানে ম্যাট উইলিয়ামসনের আরও একটি উত্তর রয়েছে যার একটি মন্তব্য হওয়া উচিত: ড্যানিয়েলপুঙ্কাসের সমাধানটি ব্যবহার করবেন না। এটি দুর্দান্ত শর্টকাট বলে ভেবে আমি এটি ব্যবহার করেছি তবে এখন আমার এ * অ্যালগোরিদমটি কেন ভেঙে গেছে তা জানার জন্য আমি কেবল মাত্র 3 ঘন্টা ব্যয় করেছি। এটি ভুল সেট ফিরে কারণ!
জর্জি স্কলি

1
'ভুল সেট' বলতে কী বোঝায়? বিপরীত ক্রমে নয় এমন একটি অ্যারে?
সিমো সালমেনেন

31
আমি আর এই বাগটি পুনরুত্পাদন করতে পারছি না। এটা আমার ত্রুটি হতে পারে। এটি একটি খুব মার্জিত সমাধান।
ম্যাট উইলিয়ামসন

3
ডকুমেন্টেশনে এখন অর্ডারটির গ্যারান্টি রয়েছে।
jscs

আমি নিশ্চিত এটি ভাল উত্তর তবে এটি মিউটেবল অবজেক্টের জন্য ব্যর্থ হবে। কারণ এনএসইউনিমরেটর কেবলমাত্র পঠনযোগ্য অবজেক্ট টাইপ @ প্রপার্টি প্রদান করে (কেবল পঠনযোগ্য, অনুলিপি)
অনুরাগ সনি

49

কিছু মানদণ্ড

1. reversObjectEnumerator allObjects

এটি দ্রুততম পদ্ধতি:

NSArray *anArray = @[@"aa", @"ab", @"ac", @"ad", @"ae", @"af", @"ag",
        @"ah", @"ai", @"aj", @"ak", @"al", @"am", @"an", @"ao", @"ap", @"aq", @"ar", @"as", @"at",
        @"au", @"av", @"aw", @"ax", @"ay", @"az", @"ba", @"bb", @"bc", @"bd", @"bf", @"bg", @"bh",
        @"bi", @"bj", @"bk", @"bl", @"bm", @"bn", @"bo", @"bp", @"bq", @"br", @"bs", @"bt", @"bu",
        @"bv", @"bw", @"bx", @"by", @"bz", @"ca", @"cb", @"cc", @"cd", @"ce", @"cf", @"cg", @"ch",
        @"ci", @"cj", @"ck", @"cl", @"cm", @"cn", @"co", @"cp", @"cq", @"cr", @"cs", @"ct", @"cu",
        @"cv", @"cw", @"cx", @"cy", @"cz"];

NSDate *methodStart = [NSDate date];

NSArray *reversed = [[anArray reverseObjectEnumerator] allObjects];

NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f", executionTime);

ফলাফল: executionTime = 0.000026

২. একটি বিপরীতমুখীশক্তি ব্যবহারকারীর উপর আইট্রেট করা

এটি 1.5x থেকে 2.5x এর মধ্যে ধীর:

NSDate *methodStart = [NSDate date];
NSMutableArray *array = [NSMutableArray arrayWithCapacity:[anArray count]];
NSEnumerator *enumerator = [anArray reverseObjectEnumerator];
for (id element in enumerator) {
    [array addObject:element];
}
NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f", executionTime);

ফলাফল: executionTime = 0.000071

৩. সাজানোআরয়েউজিংকম্পোরেটর

এটি 30x এবং 40x ধীরের মধ্যে (এখানে কোনও আশ্চর্যের কিছু নেই):

NSDate *methodStart = [NSDate date];
NSArray *reversed = [anArray sortedArrayUsingComparator: ^(id obj1, id obj2) {
    return [anArray indexOfObject:obj1] < [anArray indexOfObject:obj2] ? NSOrderedDescending : NSOrderedAscending;
}];

NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f", executionTime);

ফলাফল: executionTime = 0.001100

সুতরাং [[anArray reverseObjectEnumerator] allObjects]স্পষ্ট বিজয়ী যখন এটি গতি এবং আরাম করার জন্য আসে।


এবং আমি কল্পনা করতে পারি যে এটি বৃহত সংখ্যক অবজেক্টের জন্য 30-40x এর চেয়ে ধীরে ধীরে বেশি হবে। আমি জানি না, বাছাই করা অ্যালগরিদমের জটিলতা কী (সর্বোত্তম কেস ও (এন * লগন)?), তবে এটি সূচকেও ডাকছে, যা সম্ভবত ও (এন) হয় the * লগইন করুন) বা অন্য কিছু। ভাল নয়!
জোসেফ হামফ্রে

1
একটি বেঞ্চমার্ক ব্যবহার সম্পর্কে কী enumerateObjectsWithOptions:NSEnumerationReverse?
ব্র্যান্ডস্ক্রিপ্ট

2
আমি সবেমাত্র একটি বেঞ্চমার্ক ব্যবহার করে করেছি enumerateObjectsWithOptions:NSEnumerationReverse- শীর্ষটি 0.000072সেকেন্ডে শেষ হয়েছে, সেকেন্ডে ব্লক পদ্ধতি 0.000009
ব্র্যান্ডস্ক্রিপ্ট

চমৎকার পর্যবেক্ষণ, এটি আমার কাছে বোধগম্য, তবে আমি মনে করি যে মৃত্যুদন্ড কার্যকর করার সময়গুলি এই সিদ্ধান্তে খুব অল্প হয় যে এক্স অ্যালগরিদমটি অন্যের তুলনায় Y গুণ বেশি দ্রুত। অ্যালগরিদম সম্পাদন কার্য সম্পাদনের জন্য আমাদের বেশ কয়েকটি বিষয় খেয়াল রাখতে হবে, যেমন, একই সাথে চলছে এমন কিছু প্রক্রিয়া আছে কি ?. উদাহরণস্বরূপ, সম্ভবত আপনি যখন প্রথম অ্যালগরিদম চালাবেন তখন আপনার আরও ক্যাশে মেমরি পাওয়া যায় এবং আরও কিছু। অধিকন্তু, কেবলমাত্র একটি ডেটা সেট রয়েছে, আমি মনে করি আমাদের উপসংহারে একাধিক ডেটা সেট (বিভিন্ন আকারের সংমিশ্রণ সহ) চালানো উচিত।
পিসম্ব্রে

21

ডাসবুটটির সঠিক দৃষ্টিভঙ্গি রয়েছে তবে তার কোডে কয়েকটি ভুল রয়েছে। এখানে একটি সম্পূর্ণ জেনেরিক কোড স্নিপেট যা স্থানে থাকা কোনও এনএস পরিবর্তনযোগ্যআরে বিপরীত করবে:

/* Algorithm: swap the object N elements from the top with the object N 
 * elements from the bottom. Integer division will wrap down, leaving 
 * the middle element untouched if count is odd.
 */
for(int i = 0; i < [array count] / 2; i++) {
    int j = [array count] - i - 1;

    [array exchangeObjectAtIndex:i withObjectAtIndex:j];
}

আপনি এটি কোনও সি ফাংশনে আবদ্ধ করতে পারেন, বা বোনাস পয়েন্টগুলির জন্য, এনএসমেটেবলআরেতে যুক্ত করতে বিভাগগুলি ব্যবহার করুন। ( [array count]সেক্ষেত্রে , 'অ্যারে' 'স্ব' হয়ে উঠবে)) আপনি ইচ্ছা করলে লুপের আগে কোনও ভেরিয়েবলকে বরাদ্দ করে এবং সেই পরিবর্তনশীলটি ব্যবহার করেও এটি অপ্টিমাইজ করতে পারেন।

আপনার যদি কেবল নিয়মিত এনএসএরে থাকে তবে এটির জায়গায় এটির বিপরীত হওয়ার কোনও উপায় নেই, কারণ এনএসআরাইগুলি সংশোধন করা যায় না। তবে আপনি একটি বিপরীত অনুলিপি তৈরি করতে পারেন:

NSMutableArray * copy = [NSMutableArray arrayWithCapacity:[array count]];

for(int i = 0; i < [array count]; i++) {
    [copy addObject:[array objectAtIndex:[array count] - i - 1]];
}

বা এটি একটি লাইনে করার জন্য এই ছোট কৌশলটি ব্যবহার করুন:

NSArray * copy = [[array reverseObjectEnumerator] allObjects];

আপনি যদি কেবল একটি অ্যারের পিছনে পিছনে লুপ করতে চান তবে আপনি একটি for/ inলুপ ব্যবহার করতে পারেন [array reverseObjectEnumerator]তবে এটি ব্যবহার করা সম্ভবত খানিকটা দক্ষ -enumerateObjectsWithOptions:usingBlock::

[array enumerateObjectsWithOptions:NSEnumerationReverse
                        usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    // This is your loop body. Use the object in obj here. 
    // If you need the index, it's in idx.
    // (This is the best feature of this method, IMHO.)
    // Instead of using 'continue', use 'return'.
    // Instead of using 'break', set '*stop = YES' and then 'return'.
    // Making the surrounding method/block return is tricky and probably
    // requires a '__block' variable.
    // (This is the worst feature of this method, IMHO.)
}];

( দ্রষ্টব্য : 2014 সালে আরও পাঁচ বছরের ফাউন্ডেশনের অভিজ্ঞতা, একটি নতুন উদ্দেশ্য-সি বৈশিষ্ট্য এবং দুটি এবং মন্তব্যগুলির কয়েকটি টিপস সহ যথেষ্ট পরিমাণে আপডেট হয়েছে))


ওইটা কি কাজ করে? আমি মনে করি না NSMutableArray এর একটি সেটঅবজেক্ট: atIndex: পদ্ধতি রয়েছে। লুপটির জন্য প্রস্তাবিত ঠিক করার জন্য এবং এনএসএনবারের পরিবর্তে জেনেরিক আইডি ব্যবহার করার জন্য ধন্যবাদ।
হিমাদ্রি চৌধুরী

আপনি ঠিক বলেছেন, আমি যখন অন্যান্য কয়েকটি উদাহরণ পড়ি তখন আমি তা ধরলাম। এখনই স্থির।
ব্রেন্ট রয়্যাল-গর্ডন

2
আপনি যখন লুপ করবেন তখন [অ্যারে কাউন্ট] বলা হয়। এটি খুব ব্যয়বহুল। এমনকি একটি ফাংশন যা দুটি বস্তুর অবস্থান পরিবর্তন করে।
জর্জি স্কলি

8

উপরের অন্যটির উত্তরগুলি পর্যালোচনা করার পরে এবং এখানে ম্যাট গ্যালাগারের আলোচনার সন্ধান করুন

আমি এটি প্রস্তাব:

NSMutableArray * reverseArray = [NSMutableArray arrayWithCapacity:[myArray count]]; 

for (id element in [myArray reverseObjectEnumerator]) {
    [reverseArray addObject:element];
}

ম্যাট যেমন পর্যবেক্ষণ করেছেন:

উপরের ক্ষেত্রে, আপনি ভাবতে পারেন যে - [NSArray reversObjectEnumerator] লুপের প্রতিটি পুনরাবৃত্তিতে চালিত হবে - কোডটি সম্ভাব্যভাবে কমিয়ে দিচ্ছে। <...>

এর কিছুক্ষণ পরে, তিনি এইভাবে উত্তর দেন:

<...> "সংগ্রহ" এক্সপ্রেশনটি কেবল একবার মূল্যায়ন করা হয়, যখন লুপটির জন্য শুরু হয়। এটি সেরা ক্ষেত্রে, যেহেতু আপনি নিরাপদে "সংগ্রহ" এক্সপ্রেশনটিতে একটি ব্যয়বহুল ফাংশনটি লুপের প্রতি-পুনরাবৃত্তির কর্মক্ষমতাকে প্রভাবিত না করে রাখতে পারেন।


8

জর্জি শুলির বিভাগগুলি খুব সুন্দর। যাইহোক, এনএসমুটেবলআরির জন্য, সূচকগুলির জন্য এনএসইউআইন্টিজারগুলি ব্যবহার করা অ্যারেটি ফাঁকা থাকলে ক্রাশের ফলস্বরূপ। সঠিক কোডটি হ'ল:

@implementation NSMutableArray (Reverse)

- (void)reverse {
    NSInteger i = 0;
    NSInteger j = [self count] - 1;
    while (i < j) {
        [self exchangeObjectAtIndex:i
                  withObjectAtIndex:j];

        i++;
        j--;
    }
}

@end

8

বিপরীতে একটি অ্যারের গণনা করার সবচেয়ে কার্যকরী উপায়:

ব্যবহার enumerateObjectsWithOptions:NSEnumerationReverse usingBlock। উপরের @ জোহানেসফেরেনক্রুজের মানদণ্ড ব্যবহার করে এটি 8x এর চেয়ে দ্রুত সম্পন্ন করেছে [[array reverseObjectEnumerator] allObjects];:

NSDate *methodStart = [NSDate date];

[anArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    //
}];

NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f", executionTime);

7
NSMutableArray *objMyObject = [NSMutableArray arrayWithArray:[self reverseArray:objArrayToBeReversed]];

// Function reverseArray 
-(NSArray *) reverseArray : (NSArray *) myArray {   
    return [[myArray reverseObjectEnumerator] allObjects];
}

3

বিপরীত অ্যারে এবং এর মাধ্যমে লুপিং:

[[[startArray reverseObjectEnumerator] allObjects] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    ...
}];

2

এটি আপডেট করতে, সুইফটে এটি এর মাধ্যমে সহজেই করা যায়:

array.reverse()

1

আমার হিসাবে, আপনি কী বিবেচনা করেছেন যে অ্যারেটি প্রথম স্থানে বসানো হয়েছিল? আমি অনেকগুলি অবজেক্টগুলিকে একটি অ্যারে যুক্ত করার প্রক্রিয়াতে ছিলাম এবং প্রারম্ভিক সময়ে প্রতিটি সন্নিবেশ করানোর সিদ্ধান্ত নিয়েছিলাম, যে কোনও বিদ্যমান বস্তুকে একের পর এক ঠেলে দিয়েছি। এক্ষেত্রে একটি পরিবর্তনীয় অ্যারে প্রয়োজন।

NSMutableArray *myMutableArray = [[NSMutableArray alloc] initWithCapacity:1];
[myMutableArray insertObject:aNewObject atIndex:0];

1

বা স্কেল-ওয়ে:

-(NSArray *)reverse
{
    if ( self.count < 2 )
        return self;
    else
        return [[self.tail reverse] concat:[NSArray arrayWithObject:self.head]];
}

-(id)head
{
    return self.firstObject;
}

-(NSArray *)tail
{
    if ( self.count > 1 )
        return [self subarrayWithRange:NSMakeRange(1, self.count - 1)];
    else
        return @[];
}

2
পুনরাবৃত্তি স্মৃতি অনুসারে বৃহত ডেটা স্ট্রাকচারের জন্য একটি ভয়ানক ধারণা।
ইরান গোল্ডিন

যদি এটি পুচ্ছ পুনরাবৃত্তির সাথে সংকলন করে তবে এটি কোনও সমস্যা হওয়া উচিত নয়
সরল_কোড

1

এটি করার একটি সহজ উপায় আছে।

    NSArray *myArray = @[@"5",@"4",@"3",@"2",@"1"];
    NSMutableArray *myNewArray = [[NSMutableArray alloc] init]; //this object is going to be your new array with inverse order.
    for(int i=0; i<[myNewArray count]; i++){
        [myNewArray insertObject:[myNewArray objectAtIndex:i] atIndex:0];
    }
    //other way to do it
    for(NSString *eachValue in myArray){
        [myNewArray insertObject:eachValue atIndex:0];
    }

    //in both cases your new array will look like this
    NSLog(@"myNewArray: %@", myNewArray);
    //[@"1",@"2",@"3",@"4",@"5"]

আশা করি এটা কাজে লাগবে.


0

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

int n = [arr count];
for (int i=0; i<n/2; ++i) {
  id c  = [[arr objectAtIndex:i] retain];
  [arr replaceObjectAtIndex:i withObject:[arr objectAtIndex:n-i-1]];
  [arr replaceObjectAtIndex:n-i-1 withObject:c];
}

যেহেতু আপনি একটি এনএসআরাই দিয়ে শুরু করেছেন তারপরে আপনাকে প্রথমে আসল এনএসএরায় ('অরিগ্রেআরে') এর বিষয়বস্তু দিয়ে মিউটটেবল অ্যারে তৈরি করতে হবে।

NSMutableArray * arr = [[NSMutableArray alloc] init];
[arr setArray:origArray];

সম্পাদনা করুন: লুপের গণনায় স্থির এন -> এন / 2 এবং ব্রেন্টের উত্তরের পরামর্শের কারণে এনএসএনবারকে আরও জেনেরিক আইডিতে পরিবর্তন করা হয়েছে।


1
এটি কি সি তে মুক্তি পাচ্ছে না?
ক্লে সেতুর

0

যদি আপনি যা করতে চান তা যদি বিপরীতে পুনরাবৃত্তি হয় তবে এটি ব্যবহার করে দেখুন:

// iterate backwards
nextIndex = (currentIndex == 0) ? [myArray count] - 1 : (currentIndex - 1) % [myArray count];

আপনি একবারে [মাইআরকাউন্ট] করতে পারেন এবং এটি স্থানীয় ভেরিয়েবলে সংরক্ষণ করতে পারেন (আমি এটির ব্যয়বহুল বলে মনে করি), তবে আমি আরও অনুমান করছি যে সংকলকটি উপরে লেখা হিসাবে কোডের সাথে একই কাজটি করবে।



0

এটা চেষ্টা কর:

for (int i = 0; i < [arr count]; i++)
{
    NSString *str1 = [arr objectAtIndex:[arr count]-1];
    [arr insertObject:str1 atIndex:i];
    [arr removeObjectAtIndex:[arr count]-1];
}

0

এখানে একটি দুর্দান্ত ম্যাক্রো রয়েছে যা NSMutableArray বা NSArray এর জন্য কাজ করবে :

#define reverseArray(__theArray) {\
    if ([__theArray isKindOfClass:[NSMutableArray class]]) {\
        if ([(NSMutableArray *)__theArray count] > 1) {\
            NSUInteger i = 0;\
            NSUInteger j = [(NSMutableArray *)__theArray count]-1;\
            while (i < j) {\
                [(NSMutableArray *)__theArray exchangeObjectAtIndex:i\
                                                withObjectAtIndex:j];\
                i++;\
                j--;\
            }\
        }\
    } else if ([__theArray isKindOfClass:[NSArray class]]) {\
        __theArray = [[NSArray alloc] initWithArray:[[(NSArray *)__theArray reverseObjectEnumerator] allObjects]];\
    }\
}

কেবল কলটি ব্যবহার করতে: reverseArray(myArray);

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.