2015年03月04日

C#でケブンッリジ関数

   このエントリーをはてなブックマークに追加 Clip to Evernote
どう書く?orgに感謝を込めて」シリーズ その74

■問題 (出題者:lunlumo さん)
与えた文章の各単語の最初と最後の文字以外の文字を入れ替えた文章を出力する処理を実装して下さい。元の文章の与え方は特に問いません。
参考: 確かに"読めてしまう"コピペ http://www.itmedia.co.jp/news/articles/0905/08/news021.html

単語を順に取り出し、文字を入れ替えるというだけの なんの変哲もない普通のコードだと思うので、特筆すべき点はないです。
EnumWordsで返すのを string ではなく、StringBuilderにして、 Changeメソッドには、その StringBuilderオブジェクトをそのまま渡して 処理したほうがすこしは効率的かなと思いますが、分かりやすさ優先ということで。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Doukaku.Org {
    class Program {
        static void Main(string[] args) {
            string s =
    @"こんにちは みなさん おげんき ですか? わたしは げんき です。
この ぶんしょう は いぎりす の ケンブリッジ だいがく の けんきゅう の けっか
にんげん は もじ を にんしき するとき その さしいょ と さいご の もじさえ
あっていれば じゅんばん は めちゃくちゃ でも ちゃんと よめる という けんきゅう
に もとづいて わざと もじの じゅんばん を いれかえて あります。
どうです? ちゃんと よめちゃう でしょ?
ちゃんと よめたら はんのう よろしく。";
            CambridgeFunction cf = new CambridgeFunction();
            string result = cf.Convert(s);
            Console.WriteLine(result);
            Console.ReadLine();
        }
    }

    class CambridgeFunction {

        public string Convert(string s) {
            Random rnd = new Random();
            string t = s.Replace("\r\n", "\n");
            StringBuilder sb = new StringBuilder();
            foreach (var word in EnumWords(t)) {
                int len = word.Length;
                string cambridgeWord = (len > 3) ? Change(word, len) : word;
                sb.Append(cambridgeWord);
            }
            return sb.ToString();
        }

        // 単語を順に列挙。単語と単語の間の空白も列挙の中に含める。
        private IEnumerable<string> EnumWords(string s) {
            string word = "";
            foreach (var c in s) {
                if (IsDelimiter(c)) {
                    if (word.Length > 0)
                        yield return word;
                    yield return c.ToString();
                    word = "";
                } else {
                    word += c;
                }
            }
            yield return word;
        }

        private bool IsDelimiter(char c) {
            return "。、? \n".Contains(c);
        }

        private static Random rnd = new Random();
        private static string Change(string word, int len) {
            var list = word.ToList();
            int ix = rnd.Next(2, len - 1);
            char c = list[ix];
            list.RemoveAt(ix);
            list.Insert(1, c);
            return new string(list.ToArray());
        }
    }
}



 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52408062