rubyのNKFで「澤」が文字化け

NKFで入力文字コードが未指定だと文字化けする例。(eucsjisの変換)

#!/usr/bin/ruby
require 'nkf'

# 文字コードの設定
$KCODE = "u"

s = NKF.nkf('-s',"長澤")
se = NKF.nkf('-sE',"長澤")

puts("-s:")
puts(NKF.nkf('-eS',s))
puts("")
puts("-sE:")
puts(NKF.nkf('-eS',se))

s = NKF.nkf('-s',"長澤")は文字化けしますが、
se = NKF.nkf('-sE',"長澤")だと文字化けしません。
NKFのオプションは基本的に、「-s」と出力コードのみを指定してやるとOKなのだが、まれに「-sE」と出力入力コードを指定してやらないと文字化けするものがあります。上記「澤」など。
NKFを使う際は、入力コードも必ず指定するようにしましょう。
にほんブログ村 IT技術ブログへ
1票ポチッと押して下さい♪このブログのランキングが少し上がります。

TopCorder過去問〜初級3

またまた前回と同じ、TopCorderの過去問を日本語で紹介している例のブログ。
10分でコーディング | プログラミングに自信があるやつこい!!

【問題】※詳しくは上記リンクを見てください
あなたはこれからトランプを配っていきます。あなたにはトランプを配る人数、そしてトランプが渡されます。
今回はとても簡単なので例題で説明します。
例)
2つの引数がもらえます。

3
"123123123"

最初の3はプレイヤーの人数を示しています。

"123123123" はトランプの並びを示しています。あなたはこのなかのトランプを
配っていかなければなりません。

この場合、あなたのプログラムは
{"111","222","333"}
を返さなければなりません。

"111"は一番めのプレイヤーが受け取るトランプです。
"222"が2番目のプレイヤーが受け取るトランプです。
"333"が2番目のプレイヤーが受け取るトランプです。
import java.util.*;

class Cards {
	public static String[] deal(int numPlayers, String deck) {
		char[] deck_arr = deck.toCharArray();
		int person_card_count = deck_arr.length / numPlayers; //一人が持つカードの枚数

		String[] person_card_arr = new String[numPlayers]; //return値
		Arrays.fill(person_card_arr, ""); //初期化
		
		//deck_arrのどこまで見るのか
		int deck_arr_length = person_card_count * numPlayers;
		
		for (int i = 0; i < deck_arr_length; i++) {
			int person_index = i % numPlayers; //個人に割り振られたNo
			
			// その人の所持カードに、割り振られるカードを加えていく
			person_card_arr[person_index] += String.valueOf(deck_arr[i]);
		}

		return person_card_arr;
	}
	
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		
		System.out.println("人数:");
		int numPlayers = scan.nextInt();
		
		System.out.println("カード:");
		String deck = scan.next();
		
		//表示出力
		for (String s : deal(numPlayers, deck)) {
			System.out.println(s);
		}
	}
}

いや〜なかなか10分以内は厳しいですね。1回でもデバッグに引っかかるとアウト。PHPならいけると思うんですが。
ってこのブログ3問しかないんですね。これでおしまいです。

にほんブログ村 IT技術ブログへ
1票ポチッと押して下さい♪このブログのランキングが少し上がります。

TopCorder過去問〜初級2

前回と同じ、TopCorderの過去問を日本語で紹介しているブログ。
JAVA5.0でGO!! | プログラミングに自信があるやつこい!!

【問題】※詳しくは上記リンクを参照
あなたには3つの文字列の配列があたえられます。
一つ目の配列はユーザー名の配列。

{"usrA","usrB","usrC"}

2つ目の配列はそのユーザーが扱うことのできるデータの文字列の入った配列。扱うことの
できるデータが2個以上ある場合はデータがスペースで区切られています。

{"data1 data3","data2 data4","data3 data5 data6"}

3つ目の配列はデータの配列が入っています。

{"data1"}

あなたは3つ目の配列のなかにあるデータをすべて扱うことのできるユーザを探さなければなりません。

上の例の場合: usrA
import java.util.*;

class ReportAccess {
	public static String[] whoCanSee(String[] userNames, String[] allowedData, 
									String[] reportData) {

		List<String> contain_list = new ArrayList<String>();
		for (int i = 0; i < allowedData.length; i++) {
			List<String> allowed_list = Arrays.asList(allowedData[i].split(" "));

			boolean contain_flag = true;
			for (String report : reportData) {
				//reportDataの各値が全てallowed_listに含まれればOK。
				if (!allowed_list.contains(report)) {
					//1つでも含まれなければNG。ループを抜ける
					contain_flag = false;
					break;
				}
			}
			//OKだった場合、該当userNamesをリストに追加
			if (contain_flag) contain_list.add(userNames[i]);
		}

		return (String[])contain_list.toArray(new String[0]); //リストを配列に変換
	}
	
    public static void main(String args[]){
		String[] userNames = {"jim", "scott", "barbara"};
		String[] allowedData = {"users orders products", "products shipping", 
								"tracking products orders"};
		String[] reportData = {"products", "orders"};
    	
    	for (String user : whoCanSee(userNames, allowedData, reportData)) {
        	System.out.println(user);
    	}
    	
    }
}

最近PHPばかり書いているので、配列とListとMapを使い分けるのがめんどうです。

にほんブログ村 IT技術ブログへ
1票ポチッと押して下さい♪このブログのランキングが少し上がります。

TopCorder過去問〜初級1

TopCorderの過去問を日本語で紹介しているブログを見つけた。
topcoderの道1 | プログラミングに自信があるやつこい!!

上記ブログでの回答と違い、シフト文字を自由に定義できるようにしてみた。

【問題】※詳しくは上記リンクを参照
与えられた英語の大文字で構成された文字列の中の文字を、与えられた数字の分だけ左にシフトさせなさい。
たとえば、’C’を2つ左にシフトさせると’A’、’Z’を2つ左にシフトさせると’X’。
与えられる英語の文字列はAからZで、Aの次はZにシフトさせるものとする。

例1)

"VQREQFGT"
2
Returns: "TOPCODER"
import java.util.*;

class CCipher{
	public static String decode(String ciphertest, int shift) {
		char[] alpha_arr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
		char[] ciphertest_arr = ciphertest.toCharArray();
		
		for (int i = 0; i < ciphertest_arr.length; i++) {
			for (int j = 0; j < alpha_arr.length; j++) {
				if (ciphertest_arr[i] == alpha_arr[j]) {
					//ciphertest_arrの各文字をalpha_arrを使ってshift分だけずらす
					for (int k = shift; k > 0; k--) {
						if (j == 0) {
							j = alpha_arr.length - 1;
						} else {
							j--;
						}
					}
					ciphertest_arr[i] = alpha_arr[j];
				}
			}
		}
		
		return String.valueOf(ciphertest_arr);
	}
	
    public static void main(String args[]){
    	String ciphertest = "LIPPSASVPH";
    	int shift = 4;
    	
        System.out.println(decode(ciphertest, shift));
    }
}

最近ようやく、Javaのカンが取り戻せてきたかも。

にほんブログ村 IT技術ブログへ
1票ポチッと押して下さい♪このブログのランキングが少し上がります。

所持金と購入価格から最適なお釣りを算出するプログラム

偶然↓を見つけて面白そうだったのでやってみた。
大学のプログラミング課題ができません。 - 最近大学でjavaを始めたんですが課題... - Yahoo!知恵袋

// 1.所持金の貨幣枚数を計算
// 2.おつり(1の貨幣から算出可能な金額 - 買い物金額)のリストを算出
// 3.2でもとめたすべての金額について、貨幣枚数を計算
// 4.3の貨幣枚数で一番少ないものを求める

import java.util.*;

public class Kadai {
	private static int[] kahei_arr = {1000, 500, 100, 50, 10, 5, 1};
	
	// 入力:金額、出力:最小貨幣枚数map<貨幣(ex:500)、枚数>
	private static Map<Integer, Integer> getKaheiMaisuMap(int kingaku) {
		Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
		
		for (int kahei : kahei_arr) {
			int maisu = kingaku / kahei;
			kingaku = kingaku % kahei;
			map.put(kahei, maisu);
		}

		return map;
	}
	
	// 入力:貨幣枚数map<貨幣(ex:500)、枚数>、出力:算出可能な金額のリスト
	private static List<Integer> getKingakuList(Map<Integer, Integer> kahei_maisu_map) {
		List<Integer> list = new ArrayList<Integer>();
		
		for (int i=0; i <= kahei_maisu_map.get(1000) * 1000; i += 1000) {
			for (int j=0; j <= kahei_maisu_map.get(500) * 500; j += 500) {
				for (int k=0; k <= kahei_maisu_map.get(100) * 100; k += 100) {
					for (int l=0; l <= kahei_maisu_map.get(50) * 50; l += 50) {
						for (int m=0; m <= kahei_maisu_map.get(10) * 10; m += 10) {
							for (int n=0; n <= kahei_maisu_map.get(5) * 5; n += 5) {
								for (int o=0; o <= kahei_maisu_map.get(1) * 1; o += 1) {
									list.add(i+j+k+l+m+n+o);
								}
							}
						}
					}
				}
			}
		}

		return list;
	}
	
	public static void main(String[] args) {
		Scanner stdIn = new Scanner(System.in);

    	System.out.print("所持金は:");
    	int  own_kingaku = stdIn.nextInt();
		
		System.out.print("商品の値段は:");
    	int  item_price = stdIn.nextInt();
		
		while (own_kingaku < item_price) {
			System.out.print("この所持金では購入不可です。もう一度買い物金額を入力して下さい:");
    		item_price = stdIn.nextInt();
		}
		
		//所持金の貨幣枚数((金額、枚数)の組み合わせ)を計算
		Map<Integer, Integer> own_kingaku_maisu_map = getKaheiMaisuMap(own_kingaku);
		/*
		System.out.println("\n所持金の貨幣mapは");
		for (int money : kahei_arr) {
			System.out.println(money + "円: " + own_kingaku_maisu_map.get(money) + "枚");
		}
		System.out.println();
		*/
		
		//支払額の全パターンについて、おつりの金額と枚数を求めていく
		SortedMap<Integer, Integer> oturi_maisu_kingaku_map = 
			new TreeMap<Integer, Integer>(); //<お釣りの枚数、お釣りの金額>
		for (Integer shiharai_kingaku : getKingakuList(own_kingaku_maisu_map)) {
			
			if (shiharai_kingaku >= item_price) {
				int oturi_kahei_maisu = 0;
				int oturi_kingaku = shiharai_kingaku - item_price;

				//おつりの枚数を求める
				for(Map.Entry<Integer, Integer> oturi_set : getKaheiMaisuMap(oturi_kingaku).entrySet()) {
					oturi_kahei_maisu += oturi_set.getValue(); //貨幣ごとの枚数を足していく
				}
				
				//おつりの枚数と金額をマップに格納
				oturi_maisu_kingaku_map.put(oturi_kahei_maisu, oturi_kingaku);
				/*
				//支払い金額とそのお釣りの全てのパターン
				System.out.println("支払い額: " + shiharai_kingaku + "   おつり: " + 
					oturi_kingaku + "   おつり枚数: " + oturi_kahei_maisu);
				*/
			}
		}
		System.out.println();

		int oturi_min_maisu = oturi_maisu_kingaku_map.firstKey();
		int oturi_min_kingaku = oturi_maisu_kingaku_map.get(oturi_min_maisu);
		System.out.println("最適支払額は、" + (item_price + oturi_min_kingaku));
		System.out.println("そのときのお釣りは、" + oturi_min_kingaku);
		System.out.println("そのときのお釣りの数は、" + oturi_min_maisu);
	}
}

こういう適度な難易度の問題ってなかなかないですね〜。
上記のURLのベストアンサーさんとは違い、泥臭い総当り方で算出しました(たぶん誰でも理解出来るでしょう・・)。コメントをはずすと全パターンがみれて面白いです。ベストアンサーさんの方がエレガントですが、いまいちロジックが理解出来ません。。今度じっくり解析してみます。

にほんブログ村 IT技術ブログへ
1票ポチッと押して下さい♪このブログのランキングが少し上がります。

プログラミングでメシが食えるか!? ★★★☆

「プログラミングでメシを食わせろ!?」の小俣 光之 さんの本。本書は実際にコーディングを行うプログラマーとして一流になるための、技術的ノウハウ・心構えなどが書かれています。技術的には難しいところまでは踏み込まず、コードもあまり出てきません。C言語のコードが少し出てきますが、C言語が分からなくても理解できるレベルです。
本書は私が、"プログラマ"になるべく転職したときに購入した本で、思い入れがあります。先日久しぶりに読み返したので、ちょっと印象に残った記述を以下にあげます。

  • プロトタイプはその日のうちに作る
  • トップダウンで開発しろ(メイン関数から作成)
  • 何でも出来るはダメ。誇ってこだわれる分野を確立せよ
  • 自分で作る製品こそこだわりをもつべき


プログラミングでメシが食えるか!?―成功するプログラマーの技術と仕事術
小俣 光之
秀和システム
売り上げランキング: 204725
おすすめ度の平均: 3.5
4 プログラミング経験者向けの本
3 前半はいいが後半が...
5 プログラミングで飯が食いたいが。
4 社会人としての「プログラマ」入門
3 技術を武器に生きたい人の基本

にほんブログ村 IT技術ブログへ
1票ポチッと押して下さい♪このブログのランキングが少し上がります。

PHPの文字列・配列・オブジェクト(インスタンス)の値渡し・参照渡しについて

<?php
require_once "test_class.php";

echo "【文字列】\n";
$sa = "aa";
$sb = $sa;
$sb = "*******";
var_dump($sa);
var_dump($sb);
echo "\n";

echo "【配列】\n";
$aa = array("aa","bb","cc");
$ab = $aa;
$ab[1] = "*******";
var_dump($aa);
var_dump($ab);
echo "\n";

echo "【オブジェクト】\n";
$oa = new Test();
$oa->setTest("aa");
$ob = $oa;
$ob->setTest("*******");
var_dump($oa->getTest());
var_dump($ob->getTest());
<?php
// "test_class.php"
class Test {
        var $test = "";

        function getTest() {
                return $this->test;
        }
        function setTest($test) {
                $this->test = $test;
        }
}


結果

【文字列】
string(2) "aa"
string(7) "*******"

【配列】
array(3) {
  [0]=>
  string(2) "aa"
  [1]=>
  string(2) "bb"
  [2]=>
  string(2) "cc"
}
array(3) {
  [0]=>
  string(2) "aa"
  [1]=>
  string(7) "*******"
  [2]=>
  string(2) "cc"
}

【オブジェクト】
string(7) "*******"
string(7) "*******"


PHPでは文字列・配列が値渡し、オブジェクト(インスタンス)は参照渡しになります。文字列・配列を参照渡ししたい場合は、

$sb = &$sa; //のように&を付けてやります。

ちなみに関数に渡すときも全く同じです。

/* $xxは、文字列・配列・オブジェクト(インスタンス) */
hoge_func($xx); //値渡し ※$xxがオブジェクト(インスタンス)の場合は参照渡しになります
hoge_func(&$xx); //参照渡し

なおJavaでは文字列が値渡し、配列・オブジェクト(インスタンス)が参照渡しになります。

にほんブログ村 IT技術ブログへ
1票ポチッと押して下さい♪このブログのランキングが少し上がります。