【第1部】C言語(K&R検証)編
0032.入力行をソートする
ソース紹介
CPPファイルに記述
function.h
#pragma once
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cctype>
using namespace std;
int readlines(char* lineptr[],int maxlines);
void writelines(char* lineptr[], int nlines);
void qsort(char* v[], int left, int right);
function.cpp
#include "function.h"
#define ALLOCSIZE 10000
static char allocbuff[ALLOCSIZE];
static char* allocp = allocbuff;
/*
メモリを確保する
*/
char* alloc(int n) {
if (allocbuff + ALLOCSIZE - allocp >= n) {
allocp += n;
return allocp - n;
}
else {
return nullptr;
}
}
/*
文字列をtからsにコピーする(ポインタ版3)
*/
void strcpy2(char* s, const char* t) {
while (*s++ = *t++)
;
}
/*
sに行を入れ、長さを返す
*/
int getline(char *s, int lim) {
char c;
int i = 0;
while (--lim > 0 && (c = cin.get()) != EOF && c != '\n') {
s[i++] = c;
}
if (c == '\n') {
s[i++] = c;
}
s[i] = '\0';
return i;
}
#define MAXLEN 1000
/*
入力を読み込む
*/
int readlines(char* lineptr[], int maxlines) {
int len, nlines;
char* p, line[MAXLEN];
nlines = 0;
while ((len = getline(line, MAXLEN)) > 0) {
if (nlines >= maxlines || (p = alloc(len)) == NULL) {
return -1;
}
else {
line[len - 1] = '\0';
strcpy2(p, line);
lineptr[nlines++] = p;
}
}
return nlines;
}
/*
出力を書きだす
*/
void writelines(char* lineptr[], int nlines) {
int i;
for (i = 0; i < nlines; i++) {
printf("%s\n", lineptr[i]);
}
}
/*
文字列を比較する
*/
int strcmp2(char* s, char* t) {
for (; *s == *t; s++, t++) {
if (*s == '\0') {
return 0;
}
}
return *s - *t;
}
/*
v[i]とv[j]を交換する
*/
void swap(char *v[], int i, int j) {
char* temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
/*
v[left]...v[right]を昇順にソートする
*/
void qsort(char* v[], int left, int right) {
if (left >= right) {
return;
}
swap(v, left, (left + right) / 2);
int last = left;
for (int i = left + 1; i <= right; i++) {
if (strcmp2(v[i], v[left]) < 0) {
swap(v, ++last, i);
}
}
swap(v, left, last);
qsort(v, left, last - 1);
qsort(v, left + 1, right);
}
main.cpp
#include "function.h"
#define MAXLINES 5000
char* lineptr[MAXLINES];
/*
入力行をソートする
*/
int main()
{
int nlines;
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
qsort(lineptr, 0, nlines - 1);
writelines(lineptr, nlines);
return 0;
}
else{
printf("error\n");
return 1;
}
return 0;
}
出力
hello
world
konnnitiha
abcdefg
amenimomakezu
kazenimomakezu
inumoarukebabouniataru
^Z
abcdefg
amenimomakezu
hello
inumoarukebabouniataru
kazenimomakezu
konnnitiha
world
サンプル説明
このサンプルは、行単位で
ソートするプログラムです。実装するために
ポインタのポインタを使用しています。
ポインタを理解するのに、大変ためになるサンプルと思います。
なおこのサンプルは、、
レポジトリの
projects/Sample0032_1にあります。
K&Rでの記述
元になったのは
第5章:ポインタと配列に記述されています。
ポインタのポインタの説明のところです。