【问题标题】:How to relocate an element in one array in C++如何在 C++ 中重新定位一个数组中的元素
【发布时间】:2021-09-24 13:11:12
【问题描述】:

我参加了这道面试题,但我失败了,所以我来这里是为了不再失败!

我有一个大小为 16 的 int 数组和一个 5

我必须将此索引中的元素打印为每个可能的数组(有 16 个),方法是将 givenIndex 处的元素移动到数组中的每个位置并推送其余元素。

例如:

int array[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int givenIndex = 6;

由于array[givenIndex] = 7,我需要将 7 移动到每个可能的位置并打印该数组。

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]

[7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16]

[1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16]

[1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16]

这是 16 例。

我正在尝试的是:

for(int i = 0;i<16;i++){
        array[i] = array[indexInsercion]
        if (i<indexInsert){
            //right shift
            array[i] = array[i+1]
        }else if(i == indexInsert){
            //no shift
        }else{
            //left shift
            array[i] = array[i-1]
        }
    }

我能得到一些帮助吗?

【问题讨论】:

  • 您期待什么结果?您是否尝试在迭代时打印这些数组?您是否尝试生成这些数组的集合?
  • 请发布您的代码的minimal reproducible example。例如indexInsercion 是什么?
  • 首先您需要rotate,因此所需的数字位于前面。然后你可以swap 想要的元素和下一个元素重复,让它“向前迈进”。
  • 提示:很多时候,当一个任务说“用数组做某事”时,你实际上并不需要用数组做某事。在这里,您无需移动元素即可获得所需的输出,因为它只是在屏幕上打印
  • 当我在面试中问这样的问题时,我不是为了查看申请人代码。我这样做是为了看看他们的想法。我想看看解决问题的过程。我的建议是不要立即跳入代码。想出一个计划,然后编码。

标签: c++ arrays algorithm


【解决方案1】:

我们只能猜测面试官希望看到什么。如果我是面试官,我希望你能保持简单。这是我认为可以期望在面试情况下从头开始编写的代码:

#include <iostream>
#include <array>

template <size_t size>
void print_replaced(const std::array<int,size>& x,size_t index){
    for (int i=0;i<size;++i){
        for (int j=0;j<i;++j) {
            if (j == index) continue;
            std::cout << x[j] << " ";
        } 
        std::cout << x[index] << " ";
        for (int j=i;j<size;++j) {
            if (j == index) continue; 
            std::cout << x[j] << " ";
        }
        std::cout << "\n";
    }
}


int main() {
    std::array<int,16> x{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    print_replaced(x,6);
}

这是解决问题的第一种方法,循环打印 16 种不同的数组元素组合。打印每一行遵循简单的逻辑:我们打印应该替换的元素之前的所有元素,然后是应该洗牌的元素,然后是剩余的元素。

这很简单,但是错了。它的输出是:

7 1 2 3 4 5 6 8 9 10 11 12 13 14 15 16 
1 7 2 3 4 5 6 8 9 10 11 12 13 14 15 16 
1 2 7 3 4 5 6 8 9 10 11 12 13 14 15 16 
1 2 3 7 4 5 6 8 9 10 11 12 13 14 15 16 
1 2 3 4 7 5 6 8 9 10 11 12 13 14 15 16 
1 2 3 4 5 7 6 8 9 10 11 12 13 14 15 16 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
1 2 3 4 5 6 8 7 9 10 11 12 13 14 15 16 
1 2 3 4 5 6 8 9 7 10 11 12 13 14 15 16 
1 2 3 4 5 6 8 9 10 7 11 12 13 14 15 16 
1 2 3 4 5 6 8 9 10 11 7 12 13 14 15 16 
1 2 3 4 5 6 8 9 10 11 12 7 13 14 15 16 
1 2 3 4 5 6 8 9 10 11 12 13 7 14 15 16 
1 2 3 4 5 6 8 9 10 11 12 13 14 7 15 16 
1 2 3 4 5 6 8 9 10 11 12 13 14 15 7 16 

有一行出现两次,最后一行不见了。

作为一名面试官,我不会对第一次尝试没有产生正确的输出感到惊讶。我不在乎那个。那不是减号。我关心的是你对此有何反应。你知道接下来的步骤吗?你有修复错误输出的策略吗?还是您只是因为第一次尝试没有设法编写正确的代码而感到恐慌?这就是我想在面试中检查的内容,然后这就是练习的结束。我想问更多不同的问题,而不是给你时间来修复所有错误并编写正确的经过良好测试的代码,因为我知道这比我们在面试中花费的时间更多。

我会留给你来修复上面的代码;)

【讨论】:

  • 我也有同样的两个错误!我也完全同意你回答的最后一部分。过程比完美答案更重要。
  • 我尽量不要惊慌,但是当你认为有其他人可能会破坏 Leetcode 时,这很难。无论如何,谢谢你,我修复了代码:)
【解决方案2】:

这是一个快速的尝试。基本上只是跟踪给定索引应该去哪里并在那里打印它以及跳过它的原始位置。

#include <iostream>

int main()
{
    int array[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
    int givenIndex = 6;

    for (int p = 0; p <= 16; ++p)
    {
        if (p != givenIndex)
        {
            std::cout << "[";
            for (int i = 0; i < 16; ++i)
            {
                if (i == p)
                {
                    if (i > 0)
                    {
                        std::cout << ",";
                    }
                    std::cout << array[givenIndex];
                }
                if (array[i] != array[givenIndex])
                {
                    if (i > 0 || p == 0)
                    {
                        std::cout << ",";
                    }
                    std::cout << array[i];
                }
            }
            if (p == 16)
            {
                std::cout << "," << array[givenIndex];
            }
            std::cout << "]\n";
        }
    }
}

输出:

[7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16]
[1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16]
[1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16]
[1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16]
[1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16]
[1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
[1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16]
[1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16]
[1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16]
[1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16]
[1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16]
[1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16]
[1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7]

【讨论】:

  • 非常感谢您的回答!我试图弄清楚为什么当 givenIndex = 5 它只打印 13 个值。例如对于随机数:[,1,9,8,5,5,6,9,5,8,0,8,6,8]
  • 随机数是一个不同的问题。此代码假定给定索引处的值只会在数组中出现一次,而if (array[i] != array[givenIndex]) 是阻止它打印的原因。一个更强大的解决方案可能是拆分内部循环以在 givenIndex 将出现在该行中的位置之前打印该值,打印 givenIndex,然后打印该行的其余部分。它看起来像一个简单的问题,但有一些有趣的边缘情况。我喜欢它作为面试风格的问题。
【解决方案3】:

如果期望只是按给定顺序打印数组的元素:

跟踪要打印的数组元素的当前索引,比如indx -

  • 如果当前元素处理的位置等于行号那么 打印givenIndex处的元素。
  • 如果indx 等于givenIndex,则跳过它并打印indx + 1 元素,否则打印indx 处的元素并将indx 增加1

实施:

#include <iostream>
#include <array>

int main() {
    std::array<int, 16> array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    std::size_t givenIndex = 6;

    for (std::size_t i = 0, indx = 0; i < array.size(); indx = 0, ++i) {
        std::cout << '[';

        for (std::size_t j = 0; j < array.size(); ++j) {
            if (j == i) {
                std::cout << array[givenIndex] << ',';
                continue;
            }

            if (indx == givenIndex) {
                ++indx;
            }

            std::cout << array[indx++] << ',';
        }

        std::cout << ']';
        std::cout << '\n';
    }

    return 0;
}

输出:

# ./a.out
[7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7,]

如果期望改变数组中元素的顺序,然后打印数组:

首先将givenIndex处的元素移动到数组的0th索引,然后-

  • 打印数组
  • 在每次迭代中,将当前元素与数组中的下一个元素交换并打印。

实施:

#include <iostream>
#include <array>

void print_array (std::array<int, 16>& array) {
    std::cout << '[';
    for (std::size_t indx = 0; indx < array.size(); ++indx) {
        std::cout << array[indx] << ',';
    }
    std::cout << ']';
    std::cout << '\n';
}

void rearrange_array_elem (std::array<int, 16>& array, std::size_t givenIndx) {
    // move the element at givneIndx to first position in array
    for (std::size_t j = givenIndx; j > 0; --j) {
        std::swap (array[j], array[j - 1]);
    }

    // print array
    print_array (array);

    for (std::size_t indx = 0; indx < array.size() - 1; ++indx) {
        // swap current element with its next element
        std::swap (array[indx], array[indx + 1]);
        print_array (array);
    }
}

int main() {
    std::array<int, 16> array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    std::size_t givenIndex = 6;

    rearrange_array_elem (array, givenIndex);

    return 0;
}

输出:

# ./a.out
[7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7,]

【讨论】:

  • 谢谢!这是精确的
  • 第一个带有std::swaps 的循环可以替换为std::rotate
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-08
  • 2021-04-14
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
相关资源
最近更新 更多