Почему я получаю «ожидаемый u32, найденный & {integer}» при вставке в вектор с использованием итераторов из ящика перестановки? - PullRequest
1 голос
/ 23 октября 2019

Я хотел создать функцию, которая возвращает структуру данных со всеми возможными комбинациями для определенной группы чисел: например: для [1, 2, 3] возврат [[1], [2], [3], [1, 2], [2,1], ..., [1, 2, 3], [2, 1, 3], ...[3, 2, 1]].

Я понимаю, что c и p - это какой-то вектор &integer, но я не могу найти способ сохранить их в массив или вектор. Я пытался сохранить его как вектор векторов, так как не думаю, что его можно сохранить как вектор массивов, поскольку массивы имеют разные размеры. Это также невозможно в виде массива векторов, поскольку я не знаю количество комбинаций в начале.

Как я могу сохранить все c и p в структуре данных, чтобы их можно было возвращать и использовать снаружи?

use permutator::{Combination, Permutation}; // 0.3.3

pub fn init() -> Vec<Vec<u32>> {
    let actions: Vec<Vec<u32>>;
    let mut data = &[1, 2, 3];
    let mut counter = 1;
    for i in 1..=data.len() {
        data.combination(i).for_each(|mut c| {
            println!("{:?}", c);
            actions.push(c);
            c.permutation().for_each(|p| {
                println!("k-perm@{} = {:?}", counter, p);
                counter += 1;
                actions.push(p);
            });
        });
    }
    actions
}

Я получаю следующую ошибку:

error[E0308]: mismatched types
  --> src/main.rs:10:26
   |
10 |             actions.push(c);
   |                          ^ expected u32, found &{integer}
   |
   = note: expected type `std::vec::Vec<u32>`
              found type `std::vec::Vec<&{integer}>`

error[E0308]: mismatched types
  --> src/main.rs:14:30
   |
14 |                 actions.push(p);
   |                              ^ expected u32, found &{integer}
   |
   = note: expected type `std::vec::Vec<u32>`
              found type `std::vec::Vec<&{integer}>`

edit: При попытке actions.push(c.iter().cloned().collect()) возвращается следующая ошибка:

error[E0277]: a collection of type `std::vec::Vec<u32>` cannot be built from an iterator over elements of type `&u32`
  --> src/rl.rs:59:44
   |
59 |             actions.push(c.iter().cloned().collect());
   |                                            ^^^^^^^ a collection of type `std::vec::Vec<u32>` cannot be built from `std::iter::Iterator<Item=&u32>`
   |
   = help: the trait `std::iter::FromIterator<&u32>` is not implemented for `std::vec::Vec<u32>`


Ответы [ 2 ]

3 голосов
/ 25 октября 2019

При попытке actions.push(c.iter().cloned().collect()) возвращается следующая ошибка ...

Это происходит потому, что c является Vec<&u32>, а .iter() перебирает ссылки на элементы,поэтому c.iter() является итератором для &&u32 с. .cloned() удаляет один из & с, но не второй. Вы можете исправить это, добавив еще один .cloned() (или .copied()), но я предпочитаю использовать .map:

actions.push(c.iter().map(|c| **c).collect());

Если вам не нужно хранить ссылки, вы можете вместо этогоshadow c с Vec<u32> для использования внутри цикла:

let c: Vec<u32> = c.into_iter().cloned().collect();

cloned работает здесь, потому что c.into_iter(), в отличие от c.iter(), использует Vec<u32> для возврата итератора по u32 s.

Я также не вижу веской причины использовать здесь for_each вместо обычного цикла for. Вот как я бы предложил написать init:

pub fn init() -> Vec<Vec<u32>> {
    let actions: Vec<Vec<u32>>;
    let data = &[1, 2, 3];
    let mut counter = 1;
    for i in 1..=data.len() {
        for c in data.combination(i) {
            let mut c = c.into_iter().cloned().collect();
            println!("{:?}", c);
            actions.push(c.clone());
            for p in c.permutation() {
                println!("k-perm@{} = {:?}", counter, p);
                counter += 1;
                actions.push(p);
            }
        }
    }
    actions
}

actions.push(p) работает здесь без .into_iter().cloned().collect(), потому что permutator::HeapPermutationIterator выполняет внутреннее клонирование.

0 голосов
/ 24 октября 2019

Я нашел способ решить эту проблему, который очень уродлив, но, поскольку я новичок в языке, это было лучшее, что я мог придумать.

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

            let mut temp:Vec<u32> = vec![];
            for z in c.iter(){
                temp.push(**z);
            }
            actions.push(temp);
...