rubyのNKFで「澤」が文字化け
NKFで入力文字コードが未指定だと文字化けする例。(euc→sjisの変換)
#!/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を使う際は、入力コードも必ず指定するようにしましょう。
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問しかないんですね。これでおしまいです。
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を使い分けるのがめんどうです。
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のカンが取り戻せてきたかも。
所持金と購入価格から最適なお釣りを算出するプログラム
偶然↓を見つけて面白そうだったのでやってみた。
大学のプログラミング課題ができません。 - 最近大学で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のベストアンサーさんとは違い、泥臭い総当り方で算出しました(たぶん誰でも理解出来るでしょう・・)。コメントをはずすと全パターンがみれて面白いです。ベストアンサーさんの方がエレガントですが、いまいちロジックが理解出来ません。。今度じっくり解析してみます。
プログラミングでメシが食えるか!? ★★★☆
「プログラミングでメシを食わせろ!?」の小俣 光之 さんの本。本書は実際にコーディングを行うプログラマーとして一流になるための、技術的ノウハウ・心構えなどが書かれています。技術的には難しいところまでは踏み込まず、コードもあまり出てきません。C言語のコードが少し出てきますが、C言語が分からなくても理解できるレベルです。
本書は私が、"プログラマ"になるべく転職したときに購入した本で、思い入れがあります。先日久しぶりに読み返したので、ちょっと印象に残った記述を以下にあげます。
- プロトタイプはその日のうちに作る
- トップダウンで開発しろ(メイン関数から作成)
- 何でも出来るはダメ。誇ってこだわれる分野を確立せよ
- 自分で作る製品こそこだわりをもつべき
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); //参照渡し