在c++中使用Sort()对2D字符数组进行排序

Sort a 2D character Array using sort() in C++

本文关键字:字符 2D 数组 排序 c++ Sort      更新时间:2023-10-16

我有一个2D字符数组(我不想使用std::string数组)。我如何排序字符串(char*)在升序根据字符串的长度使用std::sort()?

我试过以下方法。但是它不工作。

char names[100][30];
bool comp(const char* a, const char* b){
    return strlen(a)<strlen(b);
}
int main(){
    ...
    //I want to sort the first n strings 
    sort(names,names+n,comp); //n<=100
    ...
}

我发现了这些错误:

1>e:program files (x86) in emicrosoft visual studio 9.0vcincludealgorithm(3128) : error C2075: '_Val' : array initialization needs curly braces
1>        e:program files (x86) in emicrosoft visual studio 9.0vcincludealgorithm(3150) : see reference to function template instantiation 'void std::_Insertion_sort1<_BidIt,bool(__cdecl *)(const char *,const char *),char[30]>(_BidIt,_BidIt,_Pr,_Ty (*))' being compiled
1>        with
1>        [
1>            _BidIt=char (*)[30],
1>            _Pr=bool (__cdecl *)(const char *,const char *),
1>            _Ty=char [30]
1>        ]
1>        e:program files (x86) in emicrosoft visual studio 9.0vcincludealgorithm(3270) : see reference to function template instantiation 'void std::_Insertion_sort<_RanIt,bool(__cdecl *)(const char *,const char *)>(_BidIt,_BidIt,_Pr)' being compiled
1>        with
1>        [
1>            _RanIt=char (*)[30],
1>            _BidIt=char (*)[30],
1>            _Pr=bool (__cdecl *)(const char *,const char *)
1>        ]
1>        e:program files (x86) in emicrosoft visual studio 9.0vcincludealgorithm(3279) : see reference to function template instantiation 'void std::_Sort<char(*)[30],int,bool(__cdecl *)(const char *,const char *)>(_RanIt,_RanIt,_Diff,_Pr)' being compiled
1>        with
1>        [
1>            _RanIt=char (*)[30],
1>            _Diff=int,
1>            _Pr=bool (__cdecl *)(const char *,const char *)
1>        ]
1>        e:projects visual studio2008samplesamplesorting.cpp(51) : see reference to function template instantiation 'void std::sort<char(*)[30],bool(__cdecl *)(const char *,const char *)>(_RanIt,_RanIt,_Pr)' being compiled
1>        with
1>        [
1>            _RanIt=char (*)[30],
1>            _Pr=bool (__cdecl *)(const char *,const char *)
1>        ]
1>e:program files (x86) in emicrosoft visual studio 9.0vcincludealgorithm(3133) : error C2106: '=' : left operand must be l-value
1>e:program files (x86) in emicrosoft visual studio 9.0vcincludealgorithm(3140) : error C2106: '=' : left operand must be l-value
1>e:program files (x86) in emicrosoft visual studio 9.0vcincludealgorithm(3141) : error C2106: '=' : left operand must be l-value
1>Build log was saved at "file://e:projects visual studio2008samplesampleDebugBuildLog.htm"
1>sample - 4 error(s), 3 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

如果你的数据在

char names[100][30];

则不能对"指针"排序,因为该数据结构根本没有指针…只有100*30 = 3000个字符一个接一个。因此,要进行排序,您需要实际移动100行以获取其所有内容。

std::sort不能直接使用,因为数据结构是数组的数组,而数组在c++中是二等公民(例如,你不能将一个数组赋值给另一个数组)。

std::sort要求其迭代器类型参数必须为:

  • ValueSwappable和RandomAccessIterator.

解引用迭代器类型必须满足以下要求:

  • MoveAssignable和MoveConstructible.

不幸的是,数组是不可交换的(也就是说,你不能将一个数组赋值给另一个数组)。因此,不能对数组使用std::sort

你能做的是用以下方式使用std::array<std::array<char, N>, M>:

template<std::size_t N, std::size_t M>
void custom_sort(std::array<std::array<char, M>, N> &arrs) {
  std::sort(std::begin(arrs), std::end(arrs), [](auto const &a, auto const &b){ return strnlen(a.data(), M) < strnlen(b.data(), M); });
}

现场演示

@Jarod42对代码的改进

如前所述,数组不能赋值。结构可以被分配,所以这可能接近你想要的。可以填充结构数组以进行对齐。在Visual Studio 2015中,结构体数组没有填充,因此内存布局与2d数组相同。

update -更改为使用引用来比较参数,并按照Jarod42的建议切换为strnlen。

#include <algorithm>
#include <cstring>
using namespace std;
typedef struct
{
    char name[30];
}name;
name names[4] = { { "12345678" },{ "123" },{ "12345" },{ "12" } };
bool comp(const name &a, const name &b)
{
    return strnlen(a.name,30) < strnlen(b.name,30);
}
int main(){
    sort(names, names+4, comp);
    return 0;
}

你可以试试:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define M 10000
int main()
{
    char names[M][15];
    int n, i;
    scanf("%d", &n);
    for (i = 0; i < n; i++)
        scanf("%s", names[i]);
    qsort(names, n, 15, (int (*)(const void *, const void *))strcmp);
    for(i = 0; i < n; i++)
        printf("%sn", names[i]);
}