Skip to content

Instantly share code, notes, and snippets.

@komasaru
Last active September 7, 2020 06:22
Show Gist options
  • Save komasaru/525179291398345100e120b5872254e4 to your computer and use it in GitHub Desktop.
Save komasaru/525179291398345100e120b5872254e4 to your computer and use it in GitHub Desktop.
C++ source code to rank, considering same ranks(mid-rank method).
/***************************************************************
Rank of numbers (integer) (by central rank method)
$ g++ -std=c++17 -Wall -O2 --pedantic-errors -o rank_2 rank_2.cpp
DATE AUTHOR VERSION
2020.09.04 mk-mode.com 1.00 新規作成
Copyright(C) 2020 mk-mode.com All Rights Reserved.
***************************************************************/
#include <algorithm> // for count
#include <iostream> // for cout
#include <regex> // for regex_search
namespace funcs {
bool is_int(std::string s) {
std::smatch m;
std::regex re("^[+-]?\\d+$");
try {
if (!std::regex_search(s, m, re)) return false;
} catch (std::regex_error& e) {
return false;
}
return true;
}
bool rank_int(std::vector<int>& ns, std::vector<double>& rs) {
unsigned int s;
unsigned int i;
unsigned int j;
unsigned int c;
try {
s = ns.size();
for (i = 0; i < s; i++) {
c = 0;
for (j = 0; j < s; j++) {
if (ns[i] < ns[j]) c++;
}
rs.push_back(c + 1);
}
} catch (...) {
return false;
}
return true;
}
bool mid_rank(std::vector<int>& ns, std::vector<double>& rs) {
std::vector<double> rs_w; // 作業用
unsigned int i;
unsigned int j;
unsigned int c;
double s;
try {
// 一旦、通常のランク付け
if (!funcs::rank_int(ns, rs)) {
std::cout << "[ERROR] Failed to rank!" << std::endl;
return EXIT_FAILURE;
}
// ランク用 vector を作業にコピー
std::copy(rs.begin(), rs.end(), std::back_inserter(rs_w));
// 中央(平均)順位法(mid-rank)でランク付け
rs.clear();
for (i = 0; i < rs_w.size(); i++) {
c = std::count(rs_w.begin(), rs_w.end(), rs_w[i]);
s = 0;
for (j = rs_w[i]; j < rs_w[i] + c; j++) s += j;
rs.push_back(s / c);
}
} catch (...) {
return false;
}
return true;
}
void display(std::vector<int>& ns, std::vector<double>& rs) {
std::vector<int>::iterator it_n; // イテレータ
std::vector<double>::iterator it_r; // イテレータ
try {
std::cout << "---" << std::endl;
std::cout << "VALS = [";
for (it_n = ns.begin(); it_n != ns.end(); ++it_n) {
std::cout << *it_n;
if (it_n != ns.end() - 1) std::cout << ", ";
}
std::cout << "]" << std::endl;
std::cout << "RANK = [";
for (it_r = rs.begin(); it_r != rs.end(); ++it_r) {
std::cout << *it_r;
if (it_r != rs.end() - 1) std::cout << ", ";
}
std::cout << "]" << std::endl;
} catch (...) {
throw;
}
}
}
int main(int argc, char* argv[]) {
std::string buf; // 入力バッファ
std::vector<int> ns; // 入力値
std::vector<double> rs; // ランク
try {
// 値入力
while (true) {
std::cout << "n? ";
getline(std::cin, buf);
if (buf.empty()) break;
if (!funcs::is_int(buf)) {
std::cout << "NOT INTEGER !!" << std::endl;
continue;
}
ns.push_back(stoi(buf));
}
// ランク計算
if (!funcs::mid_rank(ns, rs)) {
std::cout << "[ERROR] Failed to rank!" << std::endl;
return EXIT_FAILURE;
}
// 結果出力
funcs::display(ns, rs);
} catch (...) {
std::cerr << "EXCEPTION!" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment