如何在保持它们连接到同一元素的同时对 2 个数组进行排序?

How to sort 2 arrays while keeping them connected to same element?

本文关键字:数组 排序 连接 元素      更新时间:2023-10-16

我的程序按姓氏的字母顺序排序,并将名字放在旁边,但是我希望它也按名字排序。我该怎么做?

// Before sort
for (int i = 0; i < NUM_PEOPLE; i++) {
cout << first_names[i] << "t" << last_names[i] << endl;
}
string temp;
for (int pass = 0; pass < NUM_PEOPLE - 1; pass++)
for (int i = 0; i < NUM_PEOPLE - 1; i++)
if (last_names[i] > last_names[i + 1]) {
temp = last_names[i];
last_names[i] = last_names[i + 1];
last_names[i + 1] = temp;
temp = first_names[i];
first_names[i] = first_names[i + 1];
first_names[i + 1] = temp;
}
cout << "After sort:" << endl;
for (int i = 0; i < NUM_PEOPLE; i++)
cout << last_names[i] << "t" << first_names[i]<< endl;

如果您别无选择,只能将数据放在单独的数组或容器中,则执行这些类型排序的更好方法是使用额外的索引号数组,并对索引号进行排序。

您希望以这种方式执行操作的原因是,如果您有 2 个以上的数组,则为每个需要交换的数组编写 3 行交换代码变得更加困难。 只交换一个阵列会容易得多,而不管您可能需要保持同步的阵列数量如何。

下面是一个示例:

//...
// Create an array of indices, starting from 0.
int index[NUM_PEOPLE];
for (int i = 0; i < NUM_PEOPLE; ++i)
index[i] = i;
int temp;
for (int pass = 0; pass < NUM_PEOPLE - 1; pass++)
{   
for (int i = 0; i < NUM_PEOPLE - 1; i++)
{
if (last_names[index[i]] > last_names[index[i + 1]]) 
{
temp = index[i];
index[i] = index[i + 1];
index[i + 1] = temp;
}
}
}
cout << "After sort:" << endl;
for (int i = 0; i < NUM_PEOPLE; i++)
cout << last_names[index[i]] << "t" << first_names[index[i]]<< endl;

请注意,只交换了一个项目,那就是索引数组 -first_namelast_name数组不会发生任何更改。 请注意,当以排序方式访问数组时(注意末尾的输出(,我们使用索引数组作为每个单独数组的索引。

这是一个完整的示例。


下面是使用上述相同技术的std::sort的解决方案:

#include <iostream>
#include <string>
#include <algorithm>
const int NUM_PEOPLE = 5;
int main()
{
std::string first_names[NUM_PEOPLE] = { "Joe", "Peter", "Andy", "Anny", "Drake" };
std::string last_names[NUM_PEOPLE] = { "Johnson", "Parker", "Sanchez", "Nguyen", "Bell" };
// Before sort
std::cout << "nBefore sort:n" << std::endl;
for (int i = 0; i < NUM_PEOPLE; i++) {
std::cout << first_names[i] << "t" << last_names[i] << std::endl;
}
int index[NUM_PEOPLE];
for (int i = 0; i < NUM_PEOPLE; ++i)
index[i] = i;
std::sort(index, index + NUM_PEOPLE, [&](int n1, int n2) 
{ return last_names[index[n1]] < last_names[index[n2]]; });
std::cout << "nAfter sort:n" << std::endl;
for (int i = 0; i < NUM_PEOPLE; i++)
std::cout << last_names[index[i]] << "t" << first_names[index[i]] << std::endl;
}

输出:

Before sort:
Joe Johnson
Peter   Parker
Andy    Sanchez
Anny    Nguyen
Drake   Bell
After sort:
Bell    Drake
Johnson Joe
Parker  Peter
Nguyen  Anny
Sanchez Andy

到目前为止,似乎其他答案都没有按名字排序。如果您可以使用 STL 容器和 std::sort 算法,请考虑存储 firstName、lastName 对的向量,并提供自定义比较函数来考虑名字和姓氏:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector< pair<string, string> > names;
string firstName, lastName;
while( cin >> firstName >> lastName ) {
names.emplace_back(firstName, lastName);
}
sort( names.begin(), names.end(), [](auto const& a, auto const& b) {
if( a.second < b.second ) return true;
if( a.second == b.second ) return a.first < b.first;
return false;
} );
for( auto const& name : names ) {
cout << name.first << " " << name.second << "n";
}
return 0;
}

我试图让它尽可能简单,希望你觉得这很有用。
我还添加了来自用户输入的选项。
我喜欢保持我的主要功能尽可能干净:D。

旧程序:-

// Before sort
for (int i = 0; i < NUM_PEOPLE; i++) {
cout << first_names[i] << "t" << last_names[i] << endl;
}
string temp;
for (int pass = 0; pass < NUM_PEOPLE - 1; pass++)
for (int i = 0; i < NUM_PEOPLE - 1; i++)
if (last_names[i] > last_names[i + 1]) {
temp = last_names[i];
last_names[i] = last_names[i + 1];
last_names[i + 1] = temp;
temp = first_names[i];
first_names[i] = first_names[i + 1];
first_names[i + 1] = temp;
}
cout << "After sort:" << endl;
for (int i = 0; i < NUM_PEOPLE; i++)
cout << last_names[i] << "t" << first_names[i]<< endl;

新计划:-

#include<iostream>
#include<string>
using namespace std;
const int NAMES_SIZE = 5;
void names_Function();
void input_Function(string[]);
void print_Function(string[]);
int main() {
names_Function();
return EXIT_SUCCESS;
}
void names_Function() {
string names[NAMES_SIZE] = { {"Joe Johnson"}, {"Peter Parker"}, {"Andy Sanchez"}, {"Anny Nguyen"}, {"Drake Bell"} };
//input_Function(names);
cout << "Before Sorting:-nn";
print_Function(names);
for (int i = 0; i < NAMES_SIZE; i++) {
for (int j = i + 1; j < NAMES_SIZE; j++) {
if (names[i][0] > names[j][0]) {
swap(names[i], names[j]);
}
}
}
cout << "After  Sorting:-nn";
print_Function(names);
}
void input_Function(string names[]) {
for (int i = 0; i < NAMES_SIZE; i++) {
cout << "Enter Name of Person # " << i + 1 << " : ";
getline(cin, names[i]);
}
}
void print_Function(string names[]) {
for (int i = 0; i < NAMES_SIZE; i++) {
cout << names[i] << endl;
} cout << endl;
}

输出:-

Before Sorting:-
Joe Johnson
Peter Parker
Andy Sanchez
Anny Nguyen
Drake Bell
After  Sorting:-
Andy Sanchez
Anny Nguyen
Drake Bell
Joe Johnson
Peter Parker
Press any key to continue . . . _

我建议使用STL容器。这是一种更清晰、更具可读性的方法。这是一个完整的示例程序,您可以根据自己的需求进行调整。

#include <vector>
#include <iostream>
#include <tuple>
#include <algorithm>
void print(std::vector<std::tuple<std::string, std::string>>& v)
{
using namespace std;
for (int i = 0; i < v.size(); i++)  
cout << get<0>(v[i]) << " " 
<< get<1>(v[i]) << " " << endl;
}
bool compSecondElem(const std::tuple<std::string, std::string>& a,  
const std::tuple<std::string, std::string>& b) 
{ 
using namespace std;
return (get<1>(a) < get<1>(b)); 
} 
int main()
{
using namespace std;
vector<tuple<string, string>> names;
// add to vector as (lastname, firstname)
names.push_back(make_tuple("Holmes", "Sherlock"));
names.push_back(make_tuple("Holmes", "Elizabeth"));
names.push_back(make_tuple("Liz", "Taylor"));
sort(names.begin(), names.end());  //by default this sorts by 0th element
sort(names.begin(), names.end(), compSecondElem); // use compSecondElem() to sort
print(names);
}

输出:

Holmes Elizabeth 
Holmes Sherlock 
Liz Taylor 

这应该会给你你想要的结果。我做了一些不同的内部循环,比较略有不同。这个想法是让父循环,你的通过计数,循环到你正确执行的最后一个元素。

内部循环应该看在父循环所在的当前位置之前,以便为数组中的每个元素提供比较的机会。您希望确保在满足交换条件时分别交换整行。

// Preserve our original value before reassigning.
temp = last_names[i];
// Reassign element at the position ahead of us.
last_names[i] = last_names[pass];
// Update the element at our current position stored in temp.
last_names[pass] = temp;
// Swap first names same as last names.
temp = first_names[i];
first_names[i] = first_names[pass];
first_names[pass] = temp;

完整代码片段:

int main() {
// Before sort
for (int i = 0; i < NUM_PEOPLE; i++) {
cout << first_names[i] << "t" << last_names[i] << endl;
}
string temp;
// Iterate up until the last element.
for (int pass = 0; pass < NUM_PEOPLE - 1; pass++) {
// Look one ahead of our current position for comparison purposes.
for (int i = pass + 1; i < NUM_PEOPLE; i++) {
// Compare if the last name ahead of us is smaller than our current.
if (last_names[i] < last_names[pass]) {
// Swap last names.
temp = last_names[i];
last_names[i] = last_names[pass];
last_names[pass] = temp;
// Swap first names.
temp = first_names[i];
first_names[i] = first_names[pass];
first_names[pass] = temp;
}
}
}
cout << "After sort:" << endl;
for (int i = 0; i < NUM_PEOPLE; i++)
cout << last_names[i] << "t" << first_names[i]<< endl;
return 0;
}

输出:

Before sort:
Joe Johnson
Peter   Parker
Andy    Sanchez
Anny    Nguyen
Drake   Bell
After sort:
Bell    Drake
Johnson Joe
Nguyen  Anny
Parker  Peter
Sanchez Andy```

我认为其他答案是解决问题的好方法,但它们并不能完全回答您的确切代码的问题并尝试完全返工。希望这能够以尽可能少的更改更好地解决您的确切问题。

我有点不清楚天气,或者你想要一个按姓氏排序的天气,然后如果需要的话,名字或两种单独的排序(一个用于名字,一个用于姓氏(,所以我分别对每种解释进行了两次排序。

对于第一个解释,我添加了第二个 if 语句,用于检查姓氏是否相同,然后对姓氏进行排序,如果姓氏已经按顺序排列。

对于第二种解释,我只是将其更改为按名字而不是姓氏排序,因为您的代码已经同时交换了两个名称。

#include <iostream>
#include <string>
using namespace std;

int main(){
const int NUM_PEOPLE = 7;
//sorting lastnames by length then first
cout << endl << "Version that sorts last then first names:" << endl;
string first_names[NUM_PEOPLE] = {"North","Franklin","Kanye","Ye","Bob","Tim","Arnold"};
string last_names[NUM_PEOPLE] = {"West","Smith","Johnson","West","Ash","Wolf","Kelly"};
for (int i = 0; i < NUM_PEOPLE; i++) {
cout << first_names[i] << "t" << last_names[i] << endl;
}
string temp;
for (int pass = 0; pass < NUM_PEOPLE - 1; pass++){
for (int i = 0; i < NUM_PEOPLE - 1; i++){
if (last_names[i] > last_names[i + 1]) {
temp = last_names[i];
last_names[i] = last_names[i + 1];
last_names[i + 1] = temp;
temp = first_names[i];
first_names[i] = first_names[i + 1];
first_names[i + 1] = temp;
}
else if(last_names[i] == last_names[i + 1] 
&& first_names[i] > first_names[i + 1]){
temp = first_names[i];
first_names[i] = first_names[i + 1];
first_names[i + 1] = temp;
}
}
}
cout << "After sort:" << endl;
for (int i = 0; i < NUM_PEOPLE; i++)
cout << last_names[i] << "t" << first_names[i]<< endl;
//sorting by first name length only
cout << endl << "Version that only sorts by first name length:" << endl;
string first_names2[NUM_PEOPLE] = {"North","Franklin","Kanye","Ye","Bob","Tim","Arnold"};
string last_names2[NUM_PEOPLE] = {"West","Smith","Johnson","West","Ash","Wolf","Kelly"};
for (int i = 0; i < NUM_PEOPLE; i++) {
cout << first_names[i] << "t" << last_names[i] << endl;
}
for (int pass = 0; pass < NUM_PEOPLE - 1; pass++){
for (int i = 0; i < NUM_PEOPLE - 1; i++){
if (first_names2[i] > first_names2[i + 1]) {
temp = last_names2[i];
last_names2[i] = last_names2[i + 1];
last_names2[i + 1] = temp;
temp = first_names2[i];
first_names2[i] = first_names2[i + 1];
first_names2[i + 1] = temp;
}
}
}
cout << "After sort:" << endl;
for (int i = 0; i < NUM_PEOPLE; i++)
cout << last_names2[i] << "t" << first_names2[i]<< endl;
return 0;
}

输出:

Version that sorts last then first names:
North   West
Franklin        Smith
Kanye   Johnson
Ye      West
Bob     Ash
Tim     Wolf
Arnold  Kelly
After sort:
Ash     Bob
Johnson Kanye
Kelly   Arnold
Smith   Franklin
West    North
West    Ye
Wolf    Tim
Version that only sorts by first name length:
Bob     Ash
Kanye   Johnson
Arnold  Kelly
Franklin        Smith
North   West
Ye      West
Tim     Wolf
After sort:
Kelly   Arnold
Ash     Bob
Smith   Franklin
Johnson Kanye
West    North
Wolf    Tim
West    Ye

如果这是您正在寻找的答案,我仍然建议您查看其他答案,因为其中一些可以提高您的排序效率并以更标准的c ++方式做事。