Учитывая 4 объекта, как выяснить, есть ли ровно 2, обладают определенным свойством - PullRequest
2 голосов
/ 31 марта 2010

У меня есть еще один вопрос о том, как сделать самое элегантное решение этой проблемы, поскольку я не могу позволить себе ходить в компьютерную школу прямо, поэтому мои настоящие знания в области "чистого программирования" по CS не идеальны или велики. Это в основном проблема с алгоритмом (кто-то, пожалуйста, исправьте меня, если я неправильно это использую, так как я не хочу продолжать говорить их и смущаться)

У меня есть 4 объекта. Каждый из них обладает свойством вида, которым может быть собака, кошка, свинья или обезьяна. Таким образом, примерная ситуация может быть:

object1.species = свинья object2.species = кошка object3.species = свинья object4.species = собака

Теперь, если я хочу выяснить, все ли 4 вида одинаковы, я знаю, что могу просто сказать:

if  ( (object1.species==object2.species) 
    && (object2.species==object3.species)
    && (object3.species==object4.species)
) {
    // They are all the same animal (don't care WHICH animal they are)
}

Но ведь это не так элегантно, верно? И если я вдруг захочу узнать, ТОЛЬКО 3 или 2 из них являются одним и тем же видом (не важно, какой это вид), вдруг я получаю код спагетти.

Я использую Objective C, хотя я не знаю, имеет ли это значение на самом деле, так как самое элегантное решение для этого я предполагаю, что то же самое на всех языках концептуально? У кого-нибудь есть хорошая идея?

Спасибо !!

Ответы [ 3 ]

4 голосов
/ 31 марта 2010

Вы можете использовать хеш-таблицу (или словарь в target-C) с ключом вида, увеличивая счетчик каждый раз.

Для ясности (псевдокод):

// N is 4 for your particular case
for ( int i = 0; i < N; i++ )
   hashtable[ object[i].species ]++;

hashtable[ Species.PIG ]; // number of pigs (constant)

или если вы хотите развернуть его вручную:

* +1007 *

теперь вы можете проверить вид, чтобы увидеть количество:

for each key in hashtable
    if ( hashtable[ key ] == 3 ) // species "key" has 3 items
        /* Code */

конечно, "hashtable" может быть просто простым массивом, если разновидность является просто простым перечислением / целым числом. Вышеупомянутое должно быть одной и той же теорией в любом случае.

1 голос
/ 31 марта 2010

Это как раз то, для чего наборы и подсчитанные наборы.

BOOL allSameSpecies(NSArray *animals) {
    NSSet *speciesSet = [NSSet setWithArray:[animals valueForKey:@"species"]];
    return [[speciesSet] count] == 1;
}

BOOL sameSpeciesNumber(NSArray *animals, NSUInteger targetCount) {
    NSCountedSet *speciesCounts = [NSCountedSet setWithArray:[animals valueForKey:@"species"]];
    for (id species in speciesCounts) {
        if ([speciesCounts countForObject:species] == targetCount)
            return YES;
    }
    return NO.
}
1 голос
/ 31 марта 2010

Вы можете посчитать, сколько сравнений совпадают из всех возможных сравнений. Если верно только 1 сравнение, то 2 элемента совпадают, если 3 сравнения совпадают, 3 элемента совпадают. Этот пример написан на C, вам придется самостоятельно преобразовать его в target-C.

int count = 0;
count += object1.species == object2.species;
count += object1.species == object3.species;
count += object1.species == object4.species;
count += object2.species == object2.species;
count += object2.species == object3.species;
count += object3.species == object4.species;
// count 0 - all different
// count 1 - exactly 2 are the same
// count 2 - two pairs of 2
// count 3 - exactly 3 are the same
// count 6 - all are the same

Подсчет также может быть реализован в виде цикла:

for (int i = 0; i < 4; i++)
    for (int j = i + 1; j < 4; j++)
        count += objects[i].species == objects[j].species;

Этот подход работает, только если количество объектов не превышает 5. Из-за этого и того факта, что количество сравнений масштабируется квадратично, лучше использовать хеш-таблицу, если количество объектов больше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...