如何在C 中自定义排序数组,但将其中的一部分放在未分类中

How to custom sort an array in C++, but leave a portion of it unsorted?

本文关键字:一部分 分类 自定义 排序 数组      更新时间:2023-10-16

我想对数组进行排序,但要省略其中的一部分。被排除在外的零件应由开始索引(n(和端索引(m(指定。不得对这两个指数(包括指定的两个指定的指定索引(之间的所有字段进行分类。所有其他人,包括间隔之前的距离,以及之后的时间,都应将其分类。

例如:

  • 输入串行{10 , 4 , 11 , 7 , 6 , 20}
  • 非小区间启动索引n = 1
  • 非小区间端索引m = 3
  • 输出:{ 6 , 4 , 11 , 7 , 10 , 20 }

index 1到3的字段未对4, 11, 7进行排序。

#include <iostream>
#include <algorithm>
using namespace std;
int main () {
    int arr[5] = {10, 4, 11, 7, 6, 20};
    sort (arr,arr+5);
    for (int i = 0; i < 5; i++){
        cout << arr[i] << " ";
    }
    return 0;
}

我该怎么做?

这是一种使用std::rotatestd::sort的方法。
它旋转不应排序的元素,然后对开始部分进行分类,然后旋转我们移动的元素。

#include <iostream>
#include <iterator>
#include <array>
#include <algorithm>
int main() {
    std::array<int, 6> arr = {10, 4, 11, 7, 6, 20};
    unsigned from = 1;
    unsigned to = 3;
    unsigned distance = to - from + 1;
    if (to + 1 != arr.size())
        std::rotate(arr.begin(), arr.begin() + to + 1, arr.end());
    std::sort(arr.begin(), arr.end() - distance);
    std::rotate(arr.begin() + from, arr.end() - distance, arr.end());
    for (auto v : arr)
        std::cout << v << ' ';
}

我使用了std::array而不是C风格数组。也可以在std::vector上工作。

这是范围库的不错的表演案例,例如boost.range。

我们首先创建一个切片范围,以使零件向左和向右排序固定零件。

auto left = arr | sliced(0, n);
auto right = arr | sliced(m, 6);

然后,我们创建了一个新范围,该范围连接了这两个切片

auto s = join(left, right);

和排序

auto r = sort(s);

与输出一起使用boost.range提供以下代码:

#include<iostream>
#include<algorithm>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptor/sliced.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range/join.hpp>
using namespace boost;
using namespace boost::adaptors;
int main(){
  //define original and temp arrays
  int arr[6] = {10, 4, 11, 7, 6, 20};
  auto n = 2;
  auto m = 4;
  auto left = arr | sliced(0, n);
  auto right = arr | sliced(m, 6);
  auto s = join(left, right);
  auto r = sort(s);
  std::cout << "sorted range: ";
  boost::copy(r, std::ostream_iterator<int>(std::cout, ","));
  std::cout << std::endl;
  std::cout << "array: ";
  boost::copy(arr, std::ostream_iterator<int>(std::cout, ","));
  std::cout << std::endl;
  return 0;
}

运行代码打印

sorted range: 6,7,10,20, 
array: 6,4,11,7,10,20,

由于没有涉及的数据的额外移动或复制,也应该非常有效。我也觉得它非常表现力。

您可以取出要排序的元素并将它们存储在临时数组中,然后以所需的形式重组数组。我提供了一个粗制的代码解决方案;但是,您应该考虑使用std :: vector或另一个std容器(如果要更改Orignal数组的长度,也需要使用硬编码,则需要使用sizeof(a)/sizeof(a[0])之类的内容(。

>
#include<iostream>
#include<algorithm>
int main(){
  //define original and temp arrays
  int arr[6] = {10, 4, 11, 7, 6, 20};
  int temp[3] = {0};

  //cycle through arr, remove the static elements, and store in temp array
  int k = 0;
  for(int i = 0; i < 6; i++)
  {
    if(i > 0 && i < 4)
    {
      continue;
    }
    temp[k] = arr[i];
    k++;
  }
  //sort the temp array
  std::sort(temp, temp + 3);
  //restructure the array by placing the static elements back into the original array
  k = 0;
  for (int i = 0; i < 6; i++)
  {
    if (i > 0 && i < 4)
    {
      continue;
    }
    arr[i] = temp[k];
    k++;
  }
  //print out the sorted array with static elements
  for(int i = 0; i < 6; i++)
  {
    std::cout << arr[i] << " ";
  }
  return 0;
}

我提供了两个解决方案:

  • 对临时副本进行分类,然后将排序的项目放回原始列表
  • 创建数据的几个视图,然后对数据的视图之一进行排序

解决方案ONE - 丢失条目1-3的临时数组。对临时性进行排序,然后将临时性放回原始数组中。为了制作此"挽回",我使用一个索引阵列,这是我原始数组中的查找,以从哪里拉出值并将值推回:

#include <iostream>
#include <algorithm>
using namespace std;
int main(int argc, char* argv[]) {
  int arr[6] = { 10, 4, 11, 7, 6, 20 };
  int index[3] = { 0, 4, 5 };
  int tmp[3];
  for (int i = 0; i < 3; i++)
    tmp[i] = arr[index[i]];
  sort(tmp, tmp + 3);
  for (int i = 0; i < 3; i++)
    arr[index[i]] = tmp[i];
  for (int i = 0; i < 6; i++)
    cout << arr[i] << " ";
  cout << "n";
  return 0;
}

解决方案两个 - 使用自定义比较器对数组的子集进行分类:

#include <iostream>
#include <algorithm>
using namespace std;
bool compare(int *a, int *b) {
  return *a < *b;
}
int main(int argc, char* argv[]) {
  int arr[6] = { 10, 4, 11, 7 , 6, 20 };
  int* sorted[3] = { &arr[0], &arr[4], &arr[5] };
  int* skip[3] = { &arr[1], &arr[2], &arr[3] };
  int** arr2[6] = { &sorted[0], &skip[0], &skip[1], &skip[2], &sorted[1], &sorted[2] };
  sort(sorted, sorted + 3, compare);
  for (int i = 0; i < 6; i++)
    cout << **arr2[i] << " ";
  return 0;
}