2017年12月05日
《その163》 名前空間 & p.129演習3-12
名前空間
次のプログラムの、Ns_a,Ns_b はそれぞれ名前空間です。
// ------------------------------------
#include <iostream>
using namespace std;
namespace Ns_a {
void comment() {
cout << "優勝できてよかったです!\n";
}
int acc(int n) { return n * 1.08; }
}
namespace Ns_b {
void comment() {
cout << "そろそろ引退しようかな…\n";
}
int acc(int n) { return n * 1.2; }
}
int main()
{
Ns_a::comment(); // 「優勝できてよかったです!」
Ns_b::comment(); // 「そろそろ引退しようかな…」
cout << "500円預けると1年後には" << Ns_a::acc(500)
<< "円になります。\n"; // 540円
cout << "500円預けると1年後には" << Ns_b::acc(500)
<< "円になります。\n"; // 600円
}
// ------------------------------------
namespace NamaeKuukann {
ここは、名前空間 NamaeKuukann の中です。
}
namespace Harumafuji {
ここは、名前空間 Harumafuji の中です。
}
namespace {
ここは、名前無し名前区間の中です。
この中で定義された識別子などは、この名前空間が
存在するソースファイルの中でしか通用しません。
}
新版明解C++中級編 p.129 演習3-12
次の関数を作成せよ。
void mergesort(void* base, size_t nmemb, size_t size,
int(*compar)(const void*, const void*));
マージソートのアルゴリズムを用いて安定なソートを行うものとする。
// p129_演習3-12
#include <random>
#include <string>
#include <iostream>
void mergesort(
void* base,
size_t nmemb,
size_t size,
int(*compar)(const void*, const void*)
) {
// 要素数 1以下なら何もしない。
if (nmemb <= 1) return;
// 配列 base の先頭要素へのポインタを
// キャストして、char* v に代入
char* v = reinterpret_cast<char*>(base);
// 配列用の領域を確保
char* temp = new char[nmemb * size];
// 分割位置の添字 m を決定
unsigned m = nmemb / 2;
// 分割左側から mergesort を再帰呼出し
mergesort(&v[0], m, size, compar);
// 分割右側から mergesort を再帰呼出し
mergesort(&v[m * size], nmemb - m, size, compar);
for (unsigned i = 0; i < nmemb * size; i++) {
// ソート済の左側と、
// 同じくソート済の右側を、
// 配列 temp にコピー
temp[i] = v[i];
}
unsigned p = 0; // 分割左側の最初の添字
unsigned q = m; // 分割右側の最初の添字
unsigned i = 0;
do {
if (compar(
&temp[p * size],
&temp[q * size]
) <= 0) {
for (unsigned j = 0; j < size; j++)
v[i * size + j] = temp[p * size + j];
p++;
}
else {
for (unsigned j = 0; j < size; j++)
v[i * size + j] = temp[q * size + j];
q++;
}
i++;
} while (p < m && q < nmemb);
if (p == m) {
for (; i < nmemb; i++) {
for (unsigned j = 0; j < size; j++)
v[i * size + j] = temp[q * size + j];
q++;
}
}
else if (q == nmemb) {
for (; i < nmemb; i++) {
for (unsigned j = 0; j < size; j++)
v[i * size + j] = temp[p * size + j];
p++;
}
}
delete[] temp;
}
int acmp(char* x, char* y) { // 比較関数
return strcmp(x, y);
}
int pcmp(char** x, char** y) { // 比較関数
return strcmp(*x, *y);
}
int ncmp(int* x, int* y) { // 比較関数
return *x < *y ? -1 : *x > *y ? 1 : 0;
}
int main() {
std::random_device rd;
int a[20];
int nmemb = sizeof(a) / sizeof(a[0]);
for (int i = 0; i < nmemb; i++) {
a[i] = rd() % 90 + 10;
}
std::cout << "ソート前\n";
for (int i = 0; i < nmemb; i++)
std::cout << a[i] << " ";
std::cout << '\n';
mergesort(
a,
nmemb,
sizeof(a[0]),
reinterpret_cast<int(*)(const void*, const void*)>(ncmp)
);
std::cout << "ソート後\n";
for (int i = 0; i < nmemb; i++)
std::cout << a[i] << " ";
std::cout << '\n';
std::cout << "------------------------------------\n";
char b[][5]
= { "cba", "cabd", "abc", "bcd",
"cab", "b", "a", "cba", "aa" };
nmemb = sizeof(b) / sizeof(b[0]);
std::cout << "ソート前\n";
for (int i = 0; i < nmemb; i++)
std::cout << b[i] << " ";
std::cout << '\n';
mergesort(
b,
nmemb,
sizeof(b[0]),
reinterpret_cast<int(*)(const void*, const void*)>(acmp)
);
std::cout << "ソート後\n";
for (int i = 0; i < nmemb; i++)
std::cout << b[i] << " ";
std::cout << '\n';
std::cout << "------------------------------------\n";
const char* p[]
= { "yx", "xxz", "zxy", "xwy", "xxy",
"y", "xy", "yx", "xww", "y", "zy" };
nmemb = sizeof(p) / sizeof(p[0]);
std::cout << "ソート前\n";
for (int i = 0; i < nmemb; i++)
std::cout << p[i] << " ";
std::cout << '\n';
mergesort(
p,
nmemb,
sizeof(p[0]),
reinterpret_cast<int(*)(const void*, const void*)>(pcmp)
);
std::cout << "ソート後\n";
for (int i = 0; i < nmemb; i++)
std::cout << p[i] << " ";
std::cout << '\n';
}
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7055377
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック