元の文を入れ替えて違う文にする
またテキストネタです。Objective-Cでマルコフ連鎖をやろうと思ったんですが、どうも上手くいかなったので似た感じで「元の文を入れ替えて違う文にする」のをやってみました。
流れとしてはこんな感じ。たぶんコードがめちゃくちゃだと思うので、だめだこりゃと思ったら直してください。
1.元の文を。で分割する
例:元の文 ぼくはリンゴとみかんを食べた。キミはチキンとサラダを食べた。
文1:ぼくはリンゴとみかんを食べた
文2:キミはチキンとサラダを食べた
2.文1.2それぞれに形態素解析を行って分かち書きをする(以下を参照)
http://d.hatena.ne.jp/prince9/20120917/1347873368
文1を分かち書きすると、ぼく/は/リンゴ/と/みかん/を/食べ/た
3.接尾語とその前の単語をくっつけて文字列にする
例:文1 ぼくは/リンゴと/みかんを/食べた
4.3.を配列にして、ボタンを押すとexchangeObjectAtIndexを使ってランダムに入れ替える
以下サンプルです。もっと効率の良いやり方があると思います。とにかくぐちゃぐちゃですが、とりあえず公開してみました。
分かち書きに関しては前の記事同様、こちらの記事を参考にさせて頂きました。
・ViewController.h
#import <UIKit/UIKit.h> @interface ViewController : UIViewController { //元の文 NSString *hoge; //なんちゃってマルコフ連鎖処理用の配列1 NSMutableArray *Matome; //1文目形態素解析結果の配列1 NSMutableArray *persistentArray; //1文目形態素解析結果の配列2 NSMutableArray *persistentArray2; //。で分割 NSString *str1; NSString *str2; //1つ目の文分割後統合文字列 NSString *strM1;NSString *strM2;NSString *strM3;NSString *strNokori; } - (IBAction)changeRand:(id)sender; //なんちゃってマルコフ連鎖1文目 - (void)NanMarkov1; //なんちゃってマルコフ連鎖2文目 - (void)NanMarkov2; //形態素解析1文目 - (void)token1; //形態素解析2文目 - (void)token2; @end
・ViewController.m
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. hoge = @"ぼくはリンゴとみかんを食べた。キミはチキンとサラダが好きだ。"; NSArray *names = [hoge componentsSeparatedByString:@"。"]; str1 = [names objectAtIndex:0]; str2 = [names objectAtIndex:1]; NSLog(@"1番目=%@,2番目=%@",str1,str2); [self token1]; [self token2]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)token1 { //トークン解析に必要なもの CFLocaleRef locale; // ロケール:tokenizer生成に使用 CFRange range; // 解析用範囲:tokenizer生成に使用 : のちに検知されたトークンの範囲用として使用 {//トークン解析に必要なもの:初期化 range = CFRangeMake(0, [str1 length]); locale = CFLocaleCopyCurrent();// !!!: 要CFRelease } //トークン解析してくれる子 CFStringTokenizerRef tokenizer; // トークン解析してくれるよ !!!: 要CFRelease tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, (CFStringRef)CFBridgingRetain(str1), range, kCFStringTokenizerUnitWordBoundary, locale); CFStringTokenizerTokenType tokenType; // 見つかったトークンの状態 // 最初に見つかったトークンの状態で初期化 tokenType = CFStringTokenizerGoToTokenAtIndex(tokenizer, 0); persistentArray = [NSMutableArray array]; //トークン毎ループ while (tokenType != kCFStringTokenizerTokenNone) { // // range を解析用範囲から見つかったトークンの範囲へと使用方法を変更 // range = CFStringTokenizerGetCurrentTokenRange(tokenizer); //出力結果 NSString *relustStr = [str1 substringWithRange:NSMakeRange(range.location, range.length)]; //NSLog(@"結果=%@",relustStr); //解析結果から配列を作成 [persistentArray addObject:relustStr]; tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer); } [self NanMarkov1]; CFRelease(locale); CFRelease(tokenizer); } - (void)token2 { //トークン解析に必要なもの CFLocaleRef locale2; // ロケール:tokenizer生成に使用 CFRange range2; // 解析用範囲:tokenizer生成に使用 : のちに検知されたトークンの範囲用として使用 {//トークン解析に必要なもの:初期化 range2 = CFRangeMake(0, [str2 length]); locale2 = CFLocaleCopyCurrent();// !!!: 要CFRelease } //トークン解析してくれる子 CFStringTokenizerRef tokenizer2; // トークン解析してくれるよ !!!: 要CFRelease tokenizer2 = CFStringTokenizerCreate(kCFAllocatorDefault, (CFStringRef)CFBridgingRetain(str2), range2, kCFStringTokenizerUnitWordBoundary, locale2); CFStringTokenizerTokenType tokenType2; // 見つかったトークンの状態 // 最初に見つかったトークンの状態で初期化 tokenType2 = CFStringTokenizerGoToTokenAtIndex(tokenizer2, 0); persistentArray2 = [NSMutableArray array]; //トークン毎ループ while (tokenType2 != kCFStringTokenizerTokenNone) { // // range を解析用範囲から見つかったトークンの範囲へと使用方法を変更 // range2 = CFStringTokenizerGetCurrentTokenRange(tokenizer2); //出力結果 NSString *relustStr2 = [str2 substringWithRange:NSMakeRange(range2.location, range2.length)]; //NSLog(@"結果=%@",relustStr); //解析結果から配列を作成 [persistentArray2 addObject:relustStr2]; tokenType2 = CFStringTokenizerAdvanceToNextToken(tokenizer2); } [self NanMarkov2]; CFRelease(locale2); CFRelease(tokenizer2); } - (void)NanMarkov1 { //配列をコピー NSMutableArray *copyarr = [persistentArray mutableCopy]; NSMutableArray *nokori = copyarr; int cnt = [nokori count]; if (cnt <= 6) { NSString *strLast = [nokori componentsJoinedByString:@""]; NSLog(@"そのまま=%@",strLast); } else { [nokori removeObjectsInRange:NSMakeRange(0, 6)]; //分割後 NSString *strNokoriMae = [nokori componentsJoinedByString:@""]; NSString *Bunbatumaru = @"。"; strNokori = [strNokoriMae stringByAppendingString:Bunbatumaru]; NSString *strA1 = [persistentArray objectAtIndex:0]; NSString *strA2 = [persistentArray objectAtIndex:1]; strM1 = [strA1 stringByAppendingString:strA2]; NSLog(@"最初配列0=%@",strM1); NSString *strA3 = [persistentArray objectAtIndex:2]; NSString *strA4 = [persistentArray objectAtIndex:3]; strM2 = [strA3 stringByAppendingString:strA4]; NSLog(@"2番目配列1=%@",strM2); NSString *strA5 = [persistentArray objectAtIndex:4]; NSString *strA6 = [persistentArray objectAtIndex:5]; strM3 = [strA5 stringByAppendingString:strA6]; NSLog(@"3番目配列2=%@",strM3); NSLog(@"残り配列3=%@",strNokori); } } - (void)NanMarkov2 { //配列をコピー NSMutableArray *copyarr2 = [persistentArray2 mutableCopy]; NSMutableArray *nokori2 = copyarr2; int cnt2 = [nokori2 count]; if (cnt2 <= 6) { NSString *strLast2 = [nokori2 componentsJoinedByString:@""]; NSLog(@"2文目そのまま=%@",strLast2); } else { [nokori2 removeObjectsInRange:NSMakeRange(0, 6)]; //分割後 NSString *strNokoriMae2 = [nokori2 componentsJoinedByString:@""]; NSString *Bunbatumaru2 = @"。"; NSString *strNokori2 = [strNokoriMae2 stringByAppendingString:Bunbatumaru2]; NSString *strB1 = [persistentArray2 objectAtIndex:0]; NSString *strB2 = [persistentArray2 objectAtIndex:1]; NSString *strMB1 = [strB1 stringByAppendingString:strB2]; NSLog(@"2文目最初配列0=%@",strMB1); NSString *strB3 = [persistentArray2 objectAtIndex:2]; NSString *strB4 = [persistentArray2 objectAtIndex:3]; NSString *strMB2 = [strB3 stringByAppendingString:strB4]; NSLog(@"2文目2番目配列1=%@",strMB2); NSString *strB5 = [persistentArray2 objectAtIndex:4]; NSString *strB6 = [persistentArray2 objectAtIndex:5]; NSString *strMB3 = [strB5 stringByAppendingString:strB6]; NSLog(@"2文目3番目配列2=%@",strMB3); NSLog(@"2文目残り配列3=%@",strNokori2); //1文目1+2はstrM1、1文目3+4はstrM2、1文目4+5はstrM3、1文目残りはstrNokori Matome = [NSMutableArray array]; [Matome addObject:strM1]; [Matome addObject:strM2]; [Matome addObject:strM3]; [Matome addObject:strNokori]; [Matome addObject:strMB1]; [Matome addObject:strMB2]; [Matome addObject:strMB3]; [Matome addObject:strNokori2]; } } - (IBAction)changeRand:(id)sender { int cnt2 = [Matome count]; if (cnt2 <= 3) { NSLog(@"そのまま=%@",hoge); } else { int archr = 1 + arc4random() % 3; int archr2 = 5 + arc4random() % 3; [Matome exchangeObjectAtIndex:archr withObjectAtIndex:archr2]; NSString *strRand = [Matome componentsJoinedByString:@""]; NSLog(@"最終出力=%@",strRand); } } @end