Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Теория шести рукопожатий (https://javascript.ru/forum/misc/40404-teoriya-shesti-rukopozhatijj.html)

Угумс 04.08.2013 01:45

Теория шести рукопожатий
 
Добрый день,

Подскажите пожалуйста мне нужно написать програмку типо Теории шести рукопожатий, то есть я должна создать цепь где каждое из звеньев связано с другими звеньями при чем не только в одном направлении:

друзья Kevin: Mathilde, Sophie, Aaron, Sarah
друзья Joelle: Sarah, Bob, Aaron, Louis
друзья Noah: Pascal, Julie, Mathilde
друзья Matteo: Sophie, Aaron
друзья Stephanie: Bob, Orianne
друзья Lucas: Aaron, Louis
друзья Roger: Julie
Sophie и Julie друзья
Orianne и Mathilde друзья.

Например при вводе каких нибудь двух имен програмка должна показывать связь между ними то есть:
Kevin и Pascal разделены 8 друзьями:
Kevin -> Mathilde -> Noah -> Julie -> Sophie -> Kevin -> Mathilde -> Noah -> Pascal.

структура должна быть подобна этой, при этом свойство друг это должен быть массив содержащий связь с другими друзьями:

var Maillon = function(friend1,name,friend2) {
//if (suiv === undefined)
//suiv = null;
this.name = name;
this.friend1 = friend1;
this.friend2 = friend2;

};

var Liste = function () {
this.tete = null;
this.size = 0;
this.queue = null;
};

Liste.prototype.addFirst = function(name) {
this.tete = new Maillon(name,this.tete);
if (this.size === 0)
this.queue = this.tete;
this.size++;

return this;
};

Я не знаю с чего начать как сделать что бы у каждого звена было по несколько соединений. Нужно ли мне использовать что то типа:var Kevin = new Maillon(friend1,nom,friend2);?
Подскажите пожалуйста где можно найти хоть какую нибудь информацию о том как строятся подобные звенья я нигде в интернете не нашла :(

Tim 04.08.2013 05:04

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

// Конструктор человека
var Person = function (name) {
    
    var self = this;

    this.name    = name;
    this.friends = {};

    this.AddFriends = function () {
        var max = arguments.length, man;
        while (max--) {
            man = arguments[max];                // Мой друг
            self.friends[man.name] = man;        // Моя связь с другом
            man.friends[self.name] = self;        // Связь друга со мной
        }
    };
};

// Создаём людей
var Kevin     = new Person('Kevin');
var Joelle    = new Person('Joelle');
var Noah      = new Person('Noah');
var Matteo    = new Person('Matteo');
var Stephanie = new Person('Stephanie');
var Lucas     = new Person('Lucas');
var Roger     = new Person('Roger');
var Mathilde  = new Person('Mathilde');    
var Sophie    = new Person('Sophie');
var Aaron     = new Person('Aaron');
var Sarah     = new Person('Sarah');
var Bob       = new Person('Bob');
var Louis     = new Person('Louis');
var Pascal    = new Person('Pascal');
var Julie     = new Person('Julie');
var Orianne   = new Person('Orianne');

// Дружим людей
Kevin.AddFriends(Mathilde, Sophie, Aaron, Sarah);
Joelle.AddFriends(Sarah, Bob, Aaron, Louis);
Noah.AddFriends(Pascal, Julie, Mathilde);
Matteo.AddFriends(Sophie, Aaron);
Stephanie.AddFriends(Bob, Orianne);
Lucas.AddFriends(Aaron, Louis);
Roger.AddFriends(Julie);
Sophie.AddFriends(Julie);
Orianne.AddFriends(Mathilde);

// Функция проверяющая дружбу
var isFriend = function (person1, person2) {
    var viewedPerson = {};
    var chainFriends = [];

    console.log('Ищем связь между "' + person2.name + '" и "' + person1.name + '".');

    function searchFriens(person) {
        var friend;
        viewedPerson[person.name] = true;  // Запоминаем что смотрели друзей этого человека
        chainFriends.push(person.name);    // Добавим чела в цепочку связей
        // Пройдёмся по корешам
        for (var name in person.friends) {
            friend = person.friends[name];
            // Если чел не является сам собой, нужным нам челом и раньше не исследовался
            if (friend !== person1 && friend !== person2 && viewedPerson[friend.name] === undefined) {
                searchFriens(friend);    // Рекурсивный вызов
            } else if (friend === person1) {
                // Ура, это то что нам нужно
                console.log(chainFriends.join(' -> ') + ' -> ' + person1.name);
            }
        }
        chainFriends.slice(chainFriends.length - 1, 1); // Удалим чела из цепочки
    }
    
    searchFriens(person2);
};


// Найдём связь для "Kevin" и "Pascal"
isFriend(Kevin, Pascal);



В консоли получаю такое
Код:

Ищем связь между "Pascal" и "Kevin".
Pascal -> Noah -> Mathilde -> Kevin
Pascal -> Noah -> Mathilde -> Orianne -> Stephanie -> Bob -> Joelle -> Louis -> Lucas -> Aaron -> Kevin
Pascal -> Noah -> Mathilde -> Orianne -> Stephanie -> Bob -> Joelle -> Louis -> Lucas -> Aaron -> Matteo -> Sophie -> Kevin
Pascal -> Noah -> Mathilde -> Orianne -> Stephanie -> Bob -> Joelle -> Louis -> Lucas -> Aaron -> Matteo -> Sophie -> Julie -> Roger -> Sarah -> Kevin


Tim 04.08.2013 09:43

Дзен-трансгуманист,
Интересно. Где узнал про него? Порекомендуй почитать что нибудь по алгоритмам.

Угумс 05.08.2013 00:30

Добрый день, спасибо вам большое, что помогли я бы то такого не додумалась, я только начинаю программировать, прочитала в задании что циклы использовать для поиска друзей нельзя, а чем еще можно заменить цикл?

Tim 05.08.2013 02:55

forEach
Метод arr.forEach(callback[, thisArg]) вызывает функцию callback для каждого элемента массива.

filter
Метод arr.filter(callback[, thisArg]) создаёт новый массив, в который войдут только те элементы arr, для которых вызов callback(item, i, arr) возвратит true.

map
Метод arr.map(callback[, thisArg]) создаёт новый массив, который будет состоять из результатов вызова callback(item, i, arr) для каждого элемента arr.

every/some
Метод arr.every(callback[, thisArg]) возвращает true, если вызов callback вернёт true для каждого элемента arr.

Метод arr.some(callback[, thisArg]) возвращает true, если вызов callback вернёт true для какого-нибудь элемента arr.

reduce/reduceRight
Метод arr.reduce(reduceCallback[, initialValue]) применяет функцию reduceCallback по очереди к каждому элементу массива слева направо, сохраняя при этом промежуточный результат.


http://learn.javascript.ru/array-methods#foreach

cyber 05.08.2013 11:28

Цитата:

Сообщение от Tim
forEach
Метод arr.forEach(callback[, thisArg]) вызывает функцию callback для каждого элемента массива.

в общем тот же цикл но реализован по другому.
Цитата:

Сообщение от Угумс
Добрый день, спасибо вам большое, что помогли я бы то такого не додумалась, я только начинаю программировать, прочитала в задании что циклы использовать для поиска друзей нельзя, а чем еще можно заменить цикл?

В общем цикл можно заменить правильным алгоритмом, но есть задачи в которых циклы нужны по любому ( как эта), чем меньше циклов тем лучше.

Угумс 05.08.2013 17:34

а если например вводишь имя через prompt которого нет в списке как его добавить? а потом и его друзей? мне нужно вызвать функцию Person а затем Person.addFriends? для этих имен?
У меня почему то не получается ввести имена через prompt, если я их ввожу в функции isFriend то они становятся undefined.

Tim 05.08.2013 17:45

Цитата:

У меня почему то не получается ввести имена через prompt
ага, там строка по тому что, а ф-я ждёт объекты

var name  = prompt('sina pona?');
var friend = window[name];

Угумс 05.08.2013 18:50

Цитата:

Сообщение от Tim (Сообщение 265954)
ага, там строка по тому что, а ф-я ждёт объекты

var name  = prompt('sina pona?');
var friend = window[name];

все равно выдает ошибку: "TypeError: Cannot read property 'Kevin" of undefined"

Tim 06.08.2013 01:55

код в студию!


Часовой пояс GMT +3, время: 23:12.