ファイルアップロードの際、全角ファイル名部分が文字化けする現象にしばらく悩まされる。
Linuxでは問題なく、また、Windowsでもeclipseからtomcatで動かしている間は問題なかったのでしばらく気づかなかった。startup.batでtomcatを動かすと発生する不具合です。
server.xml web.xml コンテキスト設定等 文字コード関連の指定について
いろいろチェックするけれど、なかなか分からない。
ストリーム関連の文字コードについて、いろいろ調べた結果
原因は、アップロードを行うサーブレットの中にあることが判明。
ServletInputStream in = request.getInputStream();
~
in.readLine(b,0,bufsize)
というように、ストリームとしてデータを読み込み、そこから文字を取り出すため
str = new String(b,0,count-2);としていたが、これではだめらしく
str = new String(b,0,count-2,"UTF-8");としたら、うまくいった。
2014年12月29日月曜日
2014年12月23日火曜日
完全順列について
順列の中で、もとの順番とまったく一致しないものを完全順列というらしい。これをもとめるアルゴリズムを考えてみた。もっと、無駄のない方法がありそうだ(Haskellなんかだと、数行ですむようですが)が、このへんで妥協してみた。
なお、何通りか表すのがモンモール数というらしく、こちらは漸化式がWikiにあったので、それをもとにすぐ作ることができた。
#include "stdafx.h"
#include <iostream>
using namespace std;
const int imax=5;
int lst[imax],kekka[imax];
void shori(int level);
double shori2(int level);
int coun;
int _tmain(int argc, _TCHAR* argv[])
{
coun=0;
int i;
cout<<endl<<"全部で"<<shori2(imax)<<endl;
for (i=0;i<imax;i++){
kekka[i]=-1;
}
shori(0);
char dummy[1];
cin>>dummy;
return 0;
}
double shori2(int level) {//モンモール数
double x;
if(level>2){
x=(level-1)*(shori2(level-1)+shori2(level-2));
}
else{
if(level==1) x=0;
if(level==2) x=1;
}
return x;
}
void shori(int level) {//完全順列
int i,ii;
bool flg;
for(ii=0;ii<imax;++ii){
flg=true;
for(i=0;i<level;i++){
if(kekka[i]==ii){
flg=false;//親ですでに使われていないかチェック
break;
}
}
if(level!=ii && flg) {//同じ順番で親でないときはOK
kekka[level]=ii;//ここでいったん確定
if (level==imax-1){//最深レベルで出力
for(i=0;i<imax;i++){
printf("%d ", kekka[i]);
}
printf("=No.%d\n",coun) ;
coun=coun+1;
}
shori(level+1);
kekka[level]=-1;
}
}
}
なお、何通りか表すのがモンモール数というらしく、こちらは漸化式がWikiにあったので、それをもとにすぐ作ることができた。
#include "stdafx.h"
#include <iostream>
using namespace std;
const int imax=5;
int lst[imax],kekka[imax];
void shori(int level);
double shori2(int level);
int coun;
int _tmain(int argc, _TCHAR* argv[])
{
coun=0;
int i;
cout<<endl<<"全部で"<<shori2(imax)<<endl;
for (i=0;i<imax;i++){
kekka[i]=-1;
}
shori(0);
char dummy[1];
cin>>dummy;
return 0;
}
double shori2(int level) {//モンモール数
double x;
if(level>2){
x=(level-1)*(shori2(level-1)+shori2(level-2));
}
else{
if(level==1) x=0;
if(level==2) x=1;
}
return x;
}
void shori(int level) {//完全順列
int i,ii;
bool flg;
for(ii=0;ii<imax;++ii){
flg=true;
for(i=0;i<level;i++){
if(kekka[i]==ii){
flg=false;//親ですでに使われていないかチェック
break;
}
}
if(level!=ii && flg) {//同じ順番で親でないときはOK
kekka[level]=ii;//ここでいったん確定
if (level==imax-1){//最深レベルで出力
for(i=0;i<imax;i++){
printf("%d ", kekka[i]);
}
printf("=No.%d\n",coun) ;
coun=coun+1;
}
shori(level+1);
kekka[level]=-1;
}
}
}
2014年12月14日日曜日
scalaスケーラブルプログラミング P393
構造的サブ型について
Animal {type SuitableFood = Grass}
基底型(Animal)の型を 規定(Refine)する。
そして、基底型が指定されてないことも(その場合AnyRefが基底型になるそうだ)
def using[T <: {def colse():Unit},S] (obj:T) (operation:T => S) = {
val result =operation(obj)
obj.close()
result
}
このusingを使えば、 {def colse():Unit}で規定(close()メソッドを持つ型だけ)されたものをサポートするようにできるとか。上限境界を使っている。
これをうまく使えば、応用範囲は広いように思う。が、使いこなせるには、相当な慣れが必要なように思う。
Animal {type SuitableFood = Grass}
基底型(Animal)の型を 規定(Refine)する。
そして、基底型が指定されてないことも(その場合AnyRefが基底型になるそうだ)
def using[T <: {def colse():Unit},S] (obj:T) (operation:T => S) = {
val result =operation(obj)
obj.close()
result
}
このusingを使えば、 {def colse():Unit}で規定(close()メソッドを持つ型だけ)されたものをサポートするようにできるとか。上限境界を使っている。
これをうまく使えば、応用範囲は広いように思う。が、使いこなせるには、相当な慣れが必要なように思う。
scalaスケーラブルプログラミング P374
リスト 19.10 最適化された関数型待ち行列
class Queue[+T] private (
private[this] var leading: List[T],
private[this] var trailing: List[T]
) {
private def mirror() =
if (leading.isEmpty) {
while (trailing.isEmpty) {
leading =trailing.head::leading
tariling=trailing.tail
}
}
def head: T= {
mirror()
leading.head
}
def tail:Queue[T] = {
mirror()
new Queue(leading.tail,trailing)
}
def enqueue[U >: T](x: U) =
new Queue[U] (leading,x :: trailing)
}
head操作が繰り返されても、tailingからleadingへのコピーは高々1度しか行われない。
mirrorにより、leadingとtailingは中身が変化しているから。
ちなみに、リスト19.1のほうは、leadingもtrailingもvalのため、
def head = mirror.leading.headが、連続してもその都度、
def mirror = if (leading.isEmpty) new Queue(trailing.reverse,Nil) else this
が行われてしまうらしい。このとき、leading.isEmpty=trueなら、その都度tailing.reverseが
おこなわれてしまうということらしい。(def headでは、新たなQueueを返してもいないため、もとのleadingが変化しないから)
以下の
while (!trailing.isEmpty) {
leading =trailing.head::leading
tariling=trailing.tail
}
の部分は、leadingが空のときのみ行われる。
trailingが空になるまで、trailingのtailが新たにtailingとなり
trailingのheadが、leadingの先頭に追加されている。つまり、反転されてleadingに移動している。
************
ここまで読んで、scalaの実行速度を落とさないようにするには、けっこう気を付けていく
必要があるのだと感じた。
class Queue[+T] private (
private[this] var leading: List[T],
private[this] var trailing: List[T]
) {
private def mirror() =
if (leading.isEmpty) {
while (trailing.isEmpty) {
leading =trailing.head::leading
tariling=trailing.tail
}
}
def head: T= {
mirror()
leading.head
}
def tail:Queue[T] = {
mirror()
new Queue(leading.tail,trailing)
}
def enqueue[U >: T](x: U) =
new Queue[U] (leading,x :: trailing)
}
head操作が繰り返されても、tailingからleadingへのコピーは高々1度しか行われない。
mirrorにより、leadingとtailingは中身が変化しているから。
ちなみに、リスト19.1のほうは、leadingもtrailingもvalのため、
def head = mirror.leading.headが、連続してもその都度、
def mirror = if (leading.isEmpty) new Queue(trailing.reverse,Nil) else this
が行われてしまうらしい。このとき、leading.isEmpty=trueなら、その都度tailing.reverseが
おこなわれてしまうということらしい。(def headでは、新たなQueueを返してもいないため、もとのleadingが変化しないから)
以下の
while (!trailing.isEmpty) {
leading =trailing.head::leading
tariling=trailing.tail
}
の部分は、leadingが空のときのみ行われる。
trailingが空になるまで、trailingのtailが新たにtailingとなり
trailingのheadが、leadingの先頭に追加されている。つまり、反転されてleadingに移動している。
************
ここまで読んで、scalaの実行速度を落とさないようにするには、けっこう気を付けていく
必要があるのだと感じた。
2014年12月10日水曜日
シェルスクリプト 文字置換
シェルスクリプトをソフトのセットアップに使えないかと思いいろいろ試している。
設定ファイルの一部を書き換えるときなど、置換で行う方法を考えてみた。
ファイルの書き換え方がわからず、仕方なく、あまりいい方法でないが
とりあえずできればいいだろうという感じで、このようにしてみた。
echo "id:"
read id
echo "pass:"
read pas
sed -e "s/abc/$id/" -e "s/def/$pas/" config.txt >config,tmp
rm config.txt
mv config.tmp config.txt
************
その後、-iコマンドで直接ファイルを書き換えできることを知りました。
sed -i -e "s/abc/$id/" -e "s/def/$pas/" config.txt
これでいいようです
設定ファイルの一部を書き換えるときなど、置換で行う方法を考えてみた。
ファイルの書き換え方がわからず、仕方なく、あまりいい方法でないが
とりあえずできればいいだろうという感じで、このようにしてみた。
echo "id:"
read id
echo "pass:"
read pas
sed -e "s/abc/$id/" -e "s/def/$pas/" config.txt >config,tmp
rm config.txt
mv config.tmp config.txt
************
その後、-iコマンドで直接ファイルを書き換えできることを知りました。
sed -i -e "s/abc/$id/" -e "s/def/$pas/" config.txt
これでいいようです
2014年12月7日日曜日
scalaスケーラブルプログラミング P369
19章の後半の変位指定アノテーションのあたりから難しい。
クラスを宣言するトップレベルのポジションは陽性に分類されるとある。ネストの中のポジションはディフォルトではそれを囲む部分と同じだが、変化する例外がある。それは、メソッドの値パラメーターのポジションでは、メソッドの外のポジションの分類が反転するとある。メソッドの型パラメーターのポジションでも反転すると言っている。
P370でQueue[T]の定義で、Tがenqueueメソッドのパラメーターの型として現れる。Tが現れるその位置は陰性ポジションなので、、、とあるが、ここがよく理解できない。
なお、リスト19.4参照とあるが、19.1のこと?だろうか
class Queue[T]{
----------------
def enqueue(x: T) =
new Queue(leading, x :: trailing)
}
※おおざっぱにいって、戻り値なら、共変(陽性)とするが
引数なら、反変(陰性)となるということなんだろうか?
そこで、少しもどってP365のリスト19.5が次のような場合を考える
class Cell[+T](init:T){
private[this] var current = init
def get = current
def set(x:T){current =x}
これが、もしコンパイルできたとする。(実際はできないが)
val c1=new Cell[String]("abc")
val c2:Cell[Any]=c1 ←Cellは共変なので、これはOK
c2.set(1)
val s:String=c1.get
となり、コードの型に矛盾はないものの、String型の変数にInt型の値を代入することとなり、エラーとなる。
P372で、さらに具体例で、※の部分を説明している。
リスト19.8の
trait Function1[-S,+T] { 云々 }
の意味するところは、Sが反変、Tが共変 そして S =>T なる形の関数を展開したものらしい。
そしてリスト19.9で
info :Book => AnyRefには、Publication=>Stringの関数が使われている。
引数は Book extends Publication Sのほう
戻り値は String extends AnyRef Tのほう
ということで 矛盾ない構成になっている感じはする。ん~、ややこしい。
2014年12月1日月曜日
scala スケールプログラミング P.340
varを持っていても、純粋関数型になる例が出ている。
http://d.hatena.ne.jp/plasticscafe/20100906/1283745561
を参考にさせていただいた。
class Keyd {
def computeKey: Int = ...//この処理には時間がかかる
...
}
class MemoKeyed extends Keyd {
private var keyCache :Option{Int] =None
override def computeKey: Int = {
if (!keyCache.isDefined) keyCache = Some(super.computeKey)
keyCache.get
}
}
①MemoKeydのcomputeKeyでは、一回目はkeyCacheがないので、スーパークラスの
computeKeyメソッドで処理した値がkeyCacheに入る。keyCacheからデータが取り出される。
②二回目は、スーパークラスのcomputeKeyメソッドで処理はとばして、一回目に入れていた
値が、keyCacheから取り出される。
①、②いずれにしろ、同じ値がcomputeKeyからは、出てくるということで、純粋関数型とみなせる
ということのようだ。
http://d.hatena.ne.jp/plasticscafe/20100906/1283745561
を参考にさせていただいた。
class Keyd {
def computeKey: Int = ...//この処理には時間がかかる
...
}
class MemoKeyed extends Keyd {
private var keyCache :Option{Int] =None
override def computeKey: Int = {
if (!keyCache.isDefined) keyCache = Some(super.computeKey)
keyCache.get
}
}
①MemoKeydのcomputeKeyでは、一回目はkeyCacheがないので、スーパークラスの
computeKeyメソッドで処理した値がkeyCacheに入る。keyCacheからデータが取り出される。
②二回目は、スーパークラスのcomputeKeyメソッドで処理はとばして、一回目に入れていた
値が、keyCacheから取り出される。
①、②いずれにしろ、同じ値がcomputeKeyからは、出てくるということで、純粋関数型とみなせる
ということのようだ。
登録:
投稿 (Atom)