2011-06-01から1ヶ月間の記事一覧
字句がバッファサイズより長い時はバッファサイズを増やす。 #include <stdio.h> #include <stdlib.h> #include <ctype.h> typedef struct tag_token { size_t length; char *value; } Token; #define LEXER_BUFFER_INIT_SIZE 4000 #define LEXER_BUFFER_INCREASE 1000 typedef struct ta</ctype.h></stdlib.h></stdio.h>…
入力にnull文字が含まれていても間違わないように。 #include <stdio.h> #include <ctype.h> #define BUFFER_SIZE 4000 typedef struct tag_token { size_t length; char *value; } Token; typedef struct tag_lexer { Token token; char buffer[BUFFER_SIZE]; } Lexer; Token </ctype.h></stdio.h>…
空白文字を含まない最長一致文字列を字句と定義する。 字句の種類は文字列のみなので、 next_token()は字句の種類でなく字句自身へのポインタを返す。 字句はnull文字で終端している。 バッファサイズより長い字句はバッファサイズで切られてしまう。 #inclu…
遠回りしてlexerから。 next_token()は字句の種類を返す。 今のところ字句の種類はISO 646文字コードそのもの。 #include <stdio.h> int next_token(void); int next_token(void) { return getchar(); } int main(void) { int token_type; while ((token_type = next_</stdio.h>…
前述のような比較結果がほしい場合は、 数字部分列が数値として等しいが長さが異なればその差を比較結果として扱う、 という部分を変えて、長さが異なってもさらに後続部分を比較するようにすればいい。 後続部分に差が無ければ長さに差が出た最も語頭に近い…
char単位でStringを比較する普通のComparator。ただし、再帰版。 手元の環境では1000 chars長なら通るが、 10000 chars長同士の比較ではStackOverflowErrorが投げられる。 RecursiveComparator.java public class RecursiveComparator implements java.util.…
DecimalMixComparatorの比較結果は少し違和感を感じる場合があるかもしれない。 数字列を一個の仮想文字として扱っており、 一個以上の0が先行する数字列が同じ値を表現している場合は、 全体が長い方が大きい仮想文字であると定義していることによる。 値の…
Comparator全体を実装してみた。 各文字についてどちらか一方が非数字なら普通に一文字単位の比較をすればいい。 両方が数字の時だけ非負整数値としての比較を開始する。 文字といっても正確には文字単位でなくchar単位なので2 charで一文字のものには対応し…
数字部分列同士の比較の部分のおおまかな実装を妄想。こんな感じ? public int compare(String o1, String o2) { int l1 = o1.length(), l2 = o2.length(); ...snip int i; // 数字部分列の先頭のインデックス。これより前の文字列は一致している。一致して…
既述の数字列同士の比較の実装例では、 語頭の0を除いた数字列長を比較して異なればそれを結果とし、 同じ長さなら語頭の0を除いた数字列の先頭から一文字ずつ比較して異なったものがあればそれを結果とし、 全てが一致するなら語頭の0も含めた数字列全体の…
文字列同士を比較する際に文字列中に数字がある場合、 数字として一文字単位で比較するのではなく、 連続する数字のみから成る最長一致部分列を非負整数値として比較したい。 概念的には数字部分列全体を'\u002f'より大きく'\u003a'より小さい順位を持つ一文…
前掲のフローチャートを素直に実装してみる。 import java.math.BigInteger; import java.util.ArrayList; import java.util.List; public class BaseTrans { private static class IncrementalList<E> extends ArrayList<E> { /** * リストの指定された位置にある</e></e>…
CTANにあるフローチャート作成プログラムflow.cはもちろん普通にコンパイルでき普通に実行できる。 ただ警告出力の閾値低めでコンパイルしている手元の環境では少々警告が出るのでそれ用パッチ。 コンパイラが出力した警告がflowの動作に影響するようなこと…
\documentclass{jsarticle} \begin{document} \section*{位取り記数法の基数変換の一方法} $A$、$B$をそれぞれ1以上の整数とする。 ある非負整数が$M$桁の$A$進数で表記されているとき、 これを$B$進数で表記し直した場合の桁数$N$と各桁の値を求める。 $m$…
冗長だったのでもっといい加減に。 3x3以外の枡、それはもはや三目並べではない。 不正入力に対してもう少しマシな動作に。 #include <stdio.h> typedef enum { EMPTY, WHITE, BLACK, DRAW } side; static void init(void); static void show(void); static char expr</stdio.h>…
ちょっと修正パッチ。 --- sanmoku.c # +++ # # @@ -131,9 +131,8 @@ } for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; j++) { - if ((g = grid[i][j]) == EMPTY) break; + if (grid[i][j] == EMPTY) return EMPTY; } - if (g == EMPTY) break; } - re…
素朴に。人間対人間用。 #include <stdio.h> typedef enum { EMPTY, WHITE, BLACK, DRAW } piece; typedef enum { FALSE, TRUE } bool; #define SIZE 3 static piece grid[SIZE][SIZE]; static piece turn = WHITE; static char symbol[] = { ' ', 'O', 'X', '?' }; s</stdio.h>…
語頭のゼロを文字列長に含めないようにして非負整数値として比較する。 同じ値の時には語頭のゼロも含めた文字列長を比較する。 つまり、"0001" "123"である。 数字列であるかどうかの検証はしていない。 検証なしのNumericalComparatorが空文字列を通してい…
入力の正しさを誰が担保すべきかとか効率うんぬんとかは置いておいて、 Comparator内で数字だけの文字列かどうかをチェックするなら、 検証してから比較をするのではなく両者を一緒に行った方が無駄が少ない気もする。 ValidNumberComparator.java public cl…
ふとMatcher#matchesとString#charAt+数字チェックの連続とどちらの方が効率がいいのか気になった。 matcher.reset(string).matches() と比べると isDecimalString(string) ...snip private static boolean isDecimalString(String s) { int i = s.length();…
数字ではないものが比較対象に入っていたら例外を投げる。 Comparatorだけで検証する仕組みなので、 比較のためにcompareが呼び出されるたびにチェックを行う効率の悪さ。 やはり使用側が検証すべきだ。 NumericalComparator.java (deteriorated) public cla…
数字だけからなるStringを文字コード順でなく数値の大きさの昇順で比較するComparator。 NumericalComparator.java public class NumericalComparator implements java.util.Comparator<String> { public int compare(String o1, String o2) { int d = o1.length() -</string>…
ここで言うクラスはモジュール等の機能のまとまりと言い換えてもいい。 手軽にできる方法がある。それは機能の抽象化で、 果たしている機能の本質を抽出し、別のまとまりとすることで、 抽象化されたまとまりとそれを具象化するまとまりの二つにできる。 こ…
\documentclass{jsarticle} \begin{document} \section*{自然数の10進数表記から256進数表記への変換の一方法} ある自然数$x$を256進数で表記すると$N$桁になるとする。 この256進数表記での$256^n$の桁を$b_n$とする。 つまり、 \[ x = \sum_{n=0}^{N-1} 25…
\documentclass{jsarticle} \begin{document} \section*{10進数表記でn桁の自然数は256進数表記で何桁?} 自然数$m$の256進数表記での桁数$d$は、 \[ d = \lfloor \log_{256} m \rfloor + 1 \] である。$m$が10進数表記で$n$桁のとき、 \[ 10^{n-1} \le m < …
失敗。変な方向へ行こうとしている。 char *剥き出しでなくとか、そうなると出力や入力もとか、ルートになるものがとか、例外処理をとか考え始めて。 興味があることややりたいこととここでやろうとしていることは違う。 ここではC89処理系だけで数式の評価…
使用してみる。何だかぐだぐだだ。 #include <stdio.h> #include <stdlib.h> #include "expr.h" int main(void) { char e[] = "42949672961234567890"; Integer x = eval(e); if (x != NULL) { char *s = Integer_toString(x); if (s != NULL) puts(s); free(s); Integer_fin(x)</stdlib.h></stdio.h>…
いろいろ駄目なのでまじめにこつこつと。 expr.h #ifndef QS_INCLUDE_EXPR_H_ #define QS_INCLUDE_EXPR_H_ typedef struct tag_Integer *Integer; Integer eval(const char *str); void Integer_fin(Integer this); char *Integer_toString(Integer this); #…
数式とは1個以上の数字の列からなる10進数表記の非負整数である。 数式はNull文字を終端文字とするISO 646文字符号文字の列で与えられる。 #include <ctype.h> unsigned int eval(const char *expr) { unsigned int v = 0; if (*expr == '\0') return -1; do { if (! </ctype.h>…
IndexMakerの表示用メソッドshow()も少しだけ汎用性を高めてみる。 項目名や位置情報の表示用のStringはtoString()で返るというあまり無茶ではないであろう制約が加わる。 IndexMaker.java (section) ...snip private static <N extends Comparable<N>, L extends Comparable<L>> void s</l></n>…