我们可以将术语“名称的值”定义为名称中的字母,将“ A”计算为1,“ B”计算为2,“ C”计算为3,并且以此类推。 “ BOB”的值将为(2 + 15 + 2)/ 3 = 6。此值,名称将从最小到最大在输出中最大。 当两个或多个名称具有相同的值时,在原始列表中第一个位置的名称(用户输入的第一个)应首先显示在排序列表中(输出)。
输入在第一行中,我们有一个整数N(1 <= N <= 100),它是名称的数量。在N行的每一行中,我们都有一个名称([A-Z],没有空格)。名称包含1-200个字母。
输出打印出排序后的列表(一行中有一个名称)。
测试用例
输入:3 BOB AAAAAAA TOM输出:AAAAAAA BOB TOM
我尝试了一些操作,并且代码似乎可以正常工作,我的输出出现了问题。我找不到一种方法来根据名称在原始列表中的位置来排列具有相同值的名称。这是我尝试过的另一个测试用例,但没有弄清楚:
Input:
10
COSOPYILSPKNKZSTUZVMEERQDL
RRPPNG
PQUPOGTJETGXDQDEMGPNMJEBI
TQJZMOLQ
BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM
YNWEPZKNBOOXNZVWKIUS
LV
CJDFYDMYZVOEW
TMHEJLIDEHT
KGTGFIFWYTKPWTYQQPGKRRYFXN
Output: TMHEJLIDEHT PQUPOGTJETGXDQDEMGPNMJEBI BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM CJDFYDMYZVOEW RRPPNG COSOPYILSPKNKZSTUZVMEERQDL KGTGFIFWYTKPWTYQQPGKRRYFXN TQJZMOLQ YNWEPZKNBOOXNZVWKIUS LV My output: TMHEJLIDEHT PQUPOGTJETGXDQDEMGPNMJEBI CJDFYDMYZVOEW // these two BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM // should be arranged with their places switched RRPPNG COSOPYILSPKNKZSTUZVMEERQDL KGTGFIFWYTKPWTYQQPGKRRYFXN TQJZMOLQ YNWEPZKNBOOXNZVWKIUS LV
#include <iostream>
#include <string>
using namespace std;
int main() {
int N;
cin >> N;
string words[N];
int res[N];
for (int i = 0; i < N; i++) {
int sum = 0;
int value = 0;
int temp = 0;
string word;
cin >> words[i];
word = words[i];
for (int j = 0; j < word.length(); j++) {
sum += (int)word[j] - 64;
}
value = sum / word.length();
res[i] = value;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (res[i] < res[j]) {
swap(res[i], res[j]);
swap(words[i], words[j]);
}
}
}
for (int i = 0; i < N; i++) {
cout << words[i] << endl;
}
return 0;
}
string words[N];
int res[N];
这不是有效的C ++,尽管some编译器可能支持这种功能,但是您不能使用运行时变量来调整堆栈数组的大小。您可以改为使用std::vector
,它的行为很像数组。
vector<string> words;
vector<int> res;
for (int i = 0; i < N; i++) {
int sum = 0;
int value = 0;
int temp = 0;
string word;
cin >> word;
words.push_back(word);
for (int j = 0; j < word.length(); j++) {
sum += (int)word[j] - 64;
}
value = sum / word.length();
res.push_back(value);
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (res[i] < res[j]) {
swap(res[i], res[j]);
swap(words[i], words[j]);
}
}
}
排序是因为您的排序算法不稳定。稳定意味着具有相等值的项目彼此之间将保持相同的顺序。
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (res[i] < res[j]) {
swap(res[i], res[j]);
swap(words[i], words[j]);
}
}
}
您所拥有的非常接近气泡排序,这很稳定。
for (int i = 0; i < N; i++) {
for (int j = 0; j < N - i - 1; j++) { // i elements sorted so far
if (res[j] > res[j + 1]) {
swap(res[j], res[j + 1]);
swap(words[j], words[j + 1]);
}
}
}
C ++在<algorithm>
中也提供了稳定的排序,但是不幸的是,它不能直接在两个数组上运行,一个选项是即时计算值,另一种可能是使一个既包含项目又进行排序的类或其他排序索引的方法。
std::stable_sort(words.begin(), words.end(), [&](auto &a, auto &b)
{
int suma = 0, sumb = 0; // better yet, make a "int value(const string &str)" function.
for (int j = 0; j < a.length(); j++) {
suma += (int)a[j] - 64;
}
for (int j = 0; j < b.length(); j++) {
sumb += (int)b[j] - 64;
}
int valuea = suma / a.length();
int valueb = sumb / b.length();
return valuea < valueb;
});
包含两个项目的类非常简单,对于索引,请创建第三个数组并对其进行排序。
vector<size_t> indices;
...
string word;
cin >> word;
indices.push_back(words.size());
words.push_back(word);
...
std::stable_sort(indices.begin(), indices.end(), [&](auto a, auto b){ return res[a] < res[n]; });
for (int i = 0; i < N; i++) {
cout << words[indices[i]] << endl;
}
一种可能的解决方案是在构造过程中对结果数组进行排序。
当您在结果数组中添加单词时,请使用获得的结果将单词添加到正确的位置。这样,您可以检查是否已经存在相同的值,并在具有相同值的前一个单词之后添加新单词。
在python中:
def sort_list(list1, list2):
zipped_pairs = zip(list2, list1)
z = [x for _, x in sorted(zipped_pairs)]
return z
times = int(input())
entries = []
ordered = []
for x in range(times):
entries.append(input())
for x in entries:
chars = []
for y in x:
chars.append(ord(y) - 96)
ordered.append(sum(chars))
print(sort_list(entries,ordered))
或者只是在最后排序(您不需要第二个数组):
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
int sumA = 0, sumB = 0;
for (int k = 0; k < words[i].size(); k++)
sumA += words[i][k] - 'A' + 1;
for (int k = 0; k < words[j].size(); k++)
sumA += words[j][k] - 'A' + 1;
if (sumA / words[i].size() > sumB / words[j].size())
swap(words[i], words[j]);
}
}
如上所述,最好使用向量存储数据。
如果使用std::multimap<int, std::string>
,则无需排序,因为键已经用作排序标准。
这里是使用std::multimap<int, std::string>
的解决方案:
std::multimap
输出:
#include <string>
#include <numeric>
#include <iostream>
#include <sstream>
#include <map>
// Test data
std::string test = "10\n"
"COSOPYILSPKNKZSTUZVMEERQDL\n"
"RRPPNG\n"
"PQUPOGTJETGXDQDEMGPNMJEBI\n"
"TQJZMOLQ\n"
"BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM\n"
"YNWEPZKNBOOXNZVWKIUS\n"
"LV\n"
"CJDFYDMYZVOEW\n"
"TMHEJLIDEHT\n"
"KGTGFIFWYTKPWTYQQPGKRRYFXN\n";
int main()
{
std::istringstream strm(test);
// Read in the data
std::multimap<int, std::string> strmap;
int N;
strm >> N;
std::string word;
for (int i = 0; i < N; ++i)
{
strm >> word;
// get the average using std::accumulate and divide by the length of the word
int avg = std::accumulate(word.begin(), word.end(), 0,
[&](int total, char val) { return total + val - 'A' + 1; }) / word.length();
// insert this value in the map
strmap.insert({ avg, word });
}
// output results
for (auto& w : strmap)
std::cout << w.second << "\n";
}
TMHEJLIDEHT
PQUPOGTJETGXDQDEMGPNMJEBI
BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM
CJDFYDMYZVOEW
RRPPNG
COSOPYILSPKNKZSTUZVMEERQDL
KGTGFIFWYTKPWTYQQPGKRRYFXN
TQJZMOLQ
YNWEPZKNBOOXNZVWKIUS
LV
用于将这些值相加以获得平均值。