前提・実現したいこと
このサイトの Q4 の「文字数カウンタープラス」という問題の答えが39.9%になってしまいます。
正解は39.4%となっているのですが、どこが間違っているでしょうか?
ソースコード
Python
1import re 2 3moji = 0 4hiragana = 0 5 6with open('unix.txt', 'r') as txt: 7 txt = txt.read() 8 for sent in txt: 9 sent = re.findall('[ぁ-んァ-ン一-龥]', sent) 10 for word in sent: 11 if not word.isspace(): 12 moji += 1 13 if True if 'ぁ' <= word <= 'ん' else False: 14 hiragana += 1 15 16print(round(hiragana/moji*100, 1)) 17
補足情報
Python 3.6.3
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/06 23:57
回答1件
0
ベストアンサー
私も正規表現を使って計算したところ、39.9%
になりました。
私も間違えているかもしれませんが、それ以前に、この問題なにか色々とおかしいと思います。
問題文、解答例の問題
1. 問題文と解答例が食い違っている
まずcan110さんもおっしゃっている通り、問題文と解答例^1に食い違いがみられます。
というのは、この問題は、与えられたテキストファイルにふくまれるひらがな、カタカナ、漢字の文字数(以下、日本語文字数と呼びます)に占める、ひらがなの文字数の割合を求める問題であるところ、
解答例ではなぜか、日本語文字数に占めるひらがなとカタカナの文字数の割合を求めようとしているからです。
ここで「求めようとしている」と書いたのは、解答例自体に割合を求める処理が書かれていないことによります。
2. 解答例のコード自体不適である
まずこのままでは単純にビルドが通りません。(クラスやmainメソッド等は補うとして)
ビルドを通すためには、いくつかの部分でキャストが必要になるはずです。
また、解答例のコメントで数え上げ処理と書かれているブロックに問題があるため、
求めようとしている割合の分母にくるべき日本語文字数が、記号等も含んだ文字数になってしまっています。
さらに、解答例ではUnicodeBlock
を用いてひらがな、カタカナ、漢字を判定するという方針をとっていますが、ここにも落とし穴があります。
それはUnicodeBlock
でカタカナ判定をすると、その中に音引き記号の「ー」も含まれてしまうという点です。
この理由はKatakana (Unicode block)を見ればわかると思います。^2
問題文の要求には、音引き記号は日本語文字数に含めてはならないとあるので、カタカナのUnicodeBlock
に含まれる他の記号も含めて、明示的にコード中ではじく必要があります。
考察
さて、39.4%
が答えとなっている理由ですが、それは上述したカタカナ判定の問題が関係していると思います。
音引き記号等を除外せず、なるべく解答例にそった方法で計算すると39.4%
となることがその理由です。
以下に、検証用のコードですので汚いですが、解答例のコードを載せます。(!!で示した部分で主に改変した部分になります)
import java.util.*; import java.io.*; import java.lang.Character.*; public class CountJP{ public static void main(String[] args) throws Exception{ Map result = new HashMap(); //ファイルを読み込む FileReader fr = new FileReader(args[0]); BufferedReader br = new BufferedReader(fr); //一行読み込み、文字列lineに代入 String line; //数え上げ処理 while ((line = br.readLine()) != null) { for( int i = 0; i < line.length(); i++ ) { UnicodeBlock block = UnicodeBlock.of( line.charAt( i ) ); // !! ひらがな、カタカナ、漢字以外を除外 if (!CountJP.isJapanese(block)){ continue; } /* // !! カタカナに音引き記号が含まれていることの確認用 if (block.equals(UnicodeBlock.KATAKANA)){ if (String.valueOf(line.charAt(i)).equals("ー")){ System.out.println(line.charAt(i)); } } */ /* // !! カタカナ記号であれば除外 if (CountJP.isKatakanaSymbol(String.valueOf(line.charAt(i)))){ continue; } */ if( !result.containsKey( block ) ) { result.put( block, 0 ); } result.put( block, (int)result.get( block ) + 1 ); } } //文字数の合計とかなの合計を計算する int numOfChars = 0; int numOfKana = 0; for( Object key : result.keySet() ) { numOfChars += (int)result.get(key); if(key.equals(Character.UnicodeBlock.HIRAGANA)) numOfKana += (int)result.get(key); }; double ratioOfKana = (numOfKana*1.000)/numOfChars; double roundedRatioOfKana = Math.round(ratioOfKana *1000)/1000.00; System.out.printf("%.1f%%\r\n",roundedRatioOfKana * 100); } // !! ひらがな、カタカナ、漢字であるか判定 public static boolean isJapanese(UnicodeBlock block){ UnicodeBlock japaneseBlocks[] = { UnicodeBlock.HIRAGANA, UnicodeBlock.KATAKANA, UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS }; if (Arrays.asList(japaneseBlocks).contains(block)){ return true; }else{ return false; } } // !! カタカナ記号であるか判定 public static boolean isKatakanaSymbol(String str){ String symbols[] = { "゠", "・", "ー", "ヽ", "ヾ", "ヿ" }; if (Arrays.asList(symbols).contains(str)){ return true; }else{ return false; } } }
一方、上のコード例で「カタカナ記号であれば除外」とコメントされている部分をもどしてみると、39.9%
が計算結果となります。
そもそも解答例自体が解答例としておかしいので、なんともいえませんが、出題者のミスで解答例が39.4%
となっている可能性が高いと思われます。
投稿2018/03/04 05:39
退会済みユーザー
総合スコア0
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。