• ベストアンサー

題名:分割した単語を元の文章に戻したい

英文を単語ごとに分けるプログラム, (#include <stdio.h>を  (#) (include) (<) (stdio) (.) (>) にすることは出来たのですが、それを元の文章に戻すプログラムが出来ません。 元の文は一般的で単純な英文として考えての復元なのですがスペースの入れ方、が上手くいきません。 分割方法を見直すべきなのか悩んでおりますが、どなたか簡単な復元プログラムをお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • elmclose
  • ベストアンサー率31% (353/1104)
回答No.4

#1です。 書いていただいた補足に基づき、検討します。 方針としては、入力ストリームを順次読み込みながら、あるいは全部一旦バッファに格納してから、  「単語-スペース-'?'」  「単語-スペース-'.'」  「単語-スペース-'!'」 などといったパターンにマッチするかどうかを判断し、マッチした箇所を置き換える(スペースを除去する)処理をひたすら(パターンにマッチしなくなるまで)行なうプログラムを書けばよいです。 上記のパターン自体をソースコードの中に埋め込んでもOKですし、もう少し汎用性を持たせようと思えば、上記のルール自体を外部ファイルなどから読み込むようにしても良いでしょう。 このあたりのテキスト処理のプログラムを自分でC言語/C++言語などで書きたければ、「字句解析」,「有限オートマトン」などのキーワードで検索し、その理論や手法を勉強されることをお勧めします。コンパイラ作成の基礎ともなる技術です。 ご自分でプログラムを書くことにこだわらず、結果だけを手軽に得たいのでしたら、sed(stream editorの略)というプログラムを使えば、比較的簡単にできます。 書籍「sed & awkプログラミング」 http://www.amazon.co.jp/exec/obidos/ASIN/4900900583/athens-22/ 正規表現入門 http://mibai.tec.u-ryukyu.ac.jp/~oshiro/Doc/regex_primer.html これで参考になるでしょうか。頑張ってください。

その他の回答 (4)

回答No.5

C言語で字句解析なら「yacc」と「lex」ですね。 すでに使っていたらすいません。。

yosudesu
質問者

お礼

いえ、参考になりました。 どうも有難うございました。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

1.単語ごとに分割する時、スペースも含めて格納してはいかがですか。(△は1桁の空白です) △#include△<stdio.h>は (△#)(include)(△<)(stdio)(.)(h)としては、どうでしょうか。 復元するときは、単純につなげれば良いだけです。 2.何故、単語ごとに分割するのか、又、どうしてそれを復元する必要があるのか。その辺の事情を説明していただけるともっと良い回答が、得られるかもしれません。 例えば、上記の例で、 △#include△<stdio.h>と #include△△<stdio.h>は、同じ文としたいのか、そうででないのかの判断が、つきません。(△#)と(#)は、同じものとして扱いたいのかどうかも不明です。 その辺の事情も含めて説明されると良いかと思います。

yosudesu
質問者

お礼

ご回答ありがとうございます。 諸事情によりスペースは格納しないでという前提で行っています。 △#include△△△△<stdio.h>となった場合は△△△を格納しないと完全に復元出来ないと思うので、分割方法ももっとこれから検討したいと思ってます。 予定としては、△#include△△△△<stdio.h>となった場合は(△)(♯)(include)(△△△)(<)...としスペースは一個だけ入れれば完成する形にしようと考えております。 分割プログラムも行き詰まったらまたスレを立てるかもしれないのでその時もよかったらまたよろしくお願いします。

  • Rossana
  • ベストアンサー率33% (131/394)
回答No.2

whileループを使って「)」に到達するまでという条件で,繰り返し一字一字出力するっていうアルゴリズムはどうでしょうか?

yosudesu
質問者

お礼

ご回答ありがとうございます。 勉強し直して検討したいと思います。

  • elmclose
  • ベストアンサー率31% (353/1104)
回答No.1

どのような復元プログラムを作りたいのかを明確にしたほうが良いと思います。 ご質問の文面から推察すると、分割した単語間に単にスペースを入れるだけでは不十分なのでしょう。 もしそうだとすると、スペースの場所や数に関する情報を記憶していくか、そのようなスペースに関する情報を生成する規則のようなものが必要となります。 失われた情報を復元することは原理的に不可能ですので。 どうしようとしていて、何が上手くいかないのでしょうか。

yosudesu
質問者

補足

Rossanaさん、elmcloseさんご回答ありがとうございます。 説明不足で申し訳ございませんでした。 今は、テキストファイルにスペース単語スペース単語スペース\nスペース単語...と出力するプログラムは作りました。 そのスペース単語スペース単語...となっているテキストファイルを読み込み、 単語スペース? となっていたり単語スペース.や単語スペース!となっていたらそのスペースを削除。 (スペース単語となっていたらそのスペースを削除してテキストファイルを書き直すプログラムが上手くいかないので作って頂きたいという状況です。 またこれだけでの規則では完全に復元でき無いと言う事は分かっております。 完全では無いというところは目をつぶって頂けたら幸いです。

関連するQ&A

  • 複数ファイルに分割した時の構成について

    大学の卒論にむけてプログラムを書いていて、一つのmain.cでは長くなってきたので、関数を func1.h func1.c のような別ファイルに記述することにしました。 その現在の構成を、質問欄の下部に簡単に書いたので、構成が自然かどうか意見をお聞きしたいです。特に、 「include文、define文をヘッダファイルにまとめて、各ファイルからincludeしている構造」がコードの記述方法として、きもちわるくないか、一般的かどうか、教えてください。 このようにした理由は、 ・defineマクロを多くのサブ関数で利用している。 ・define定義の値を細かく変えながら実行し、結果の違いを出力したい。 ・その為、各ファイルの頭にdefine定義を置いた場合、定義の値を  いちいち全てのファイルで変更しなければならなくなり、面倒…。 →defineマクロをdefine.hにまとめた。ついでに、<stdio.h>,<math.h>なども置いてしまえばスッキリするかも~。 という経緯です。 理学の学科でまわりに詳しい人がいなく、 プログラム知識もほぼ独学なので、不安に感じて質問しました。 よろしくおねがいします。 +++++++++++++ 以下が、簡単なファイル構成です +++++++++++++ -----define.h----- #include <stdio.h> #include <math.h> #define A_MAX 3 #define B_MAX 5 -----main.c---- #include "define.h" int main() { func1(); func2(); func3(); } -----func1.h---- #include "define.h" void func1(int hoge); //プロトタイプ宣言 -----func1.c---- #include "func1.h" void func1() { hogehoge; } ------func2以下、func1と同構造

  • 分割した単語の頻出頻度を表示させたい

    英文テキストファイルを読み込み、分割した単語の頻出頻度を表示するプログラムを作成しています。 現時点では、分割した単語の表示しかできていません。 どなたか良きアドバイスをお願いします。 #include <stdio.h> int main() { int i,key,len,num ; int sp=0; char str[100000],*ptr[100000] ; FILE *fp; if ((fp=fopen("test.txt","r"))==NULL) { return -1; } num = 0 ; len = 0 ; ptr[0] = str ; do { key = fgetc(fp); str[len] = (char)key ; if ( (key==' ' && sp==0) || key == '.' || key == ',' || key == '!' || key == '?' || key == '"' || key == 0x0a || key == 0x0d ){ str[len] = '\0' ; if ( str+len-ptr[num] ){ num ++ ; } ptr[num] = str+len+1 ; if( key==',' || key=='.' || key== '!' || key=='?' || key=='"'){ str[++len]=(char)key; str[++len]='\0'; ptr[++num]=&str[len+1]; } } sp= (key== ' ')?1:0; len ++ ; } while ( key != EOF && len < 255 ); str[255] = '\0' ; for (i=0 ;i<num ;i++){ printf("%s\n",ptr[i]); } fclose(fp); return i; }

  • この円を分割して。。

    #include <stdio.h> #include <time.h> #include <stdlib.h> #define MAX 10000 void main(void) { int i; float x1, x2, en, sum=0.0, s; srand( (unsigned)time( NULL ) ); for(i=0;i<MAX;i++) { x1=((float)rand()/(float)RAND_MAX); x2=((float)rand()/(float)RAND_MAX); if(en=(x1-0.5)*(x1-0.5)+(x2-0.5)*(x2-0.5)<=(0.5)*(0.5)) { sum++; } } s=sum/MAX; printf("円の面積:%15.6e\n",s); } 円の面積を求める方法です。がもう少し精度をあげる工夫をしようと思うのですが、円を4分割した第一象限の部分に乱数をとばしその面積を求め、4倍することで求めたいのですがどうプログラムを変えたらいいか教えてください。

  • 長い文章の単語を抽出するソフト

     英訳をする時に、私は必要な単語を先に抜き出しておいて それを完全に辞書で調べてから一気に訳す・・・という方法をとるのですが、 文章のように沢山の単語でつらなっているものを、単語に分けて 抽出する・・・というようなソフトはありますか? (私はその単語をばらした後で、エクセルに貼り付けて 50音順にして重複を削除するという予定です。)  ためしにエクセルに貼り付けてみて ツールの区切り位置? みたいなのでスペースで区切ってみて単語をばらしてみようかと 思ったんですが駄目でした(涙) 何か良い方法・ソフトがないか教えてください!

  • 分割コンパイルの#defineについて

    分割コンパイルで ファイル1 #include <stdio.h> #define number 10 char string[number]; int main(void){ string[0]='a'; string[1]='b'; file_to(); return 0; } ファイル2 #include <stdio.h> #define number 10 extern char string[number]; void file_to(void){ /***何かの処理をする*****/ } って感じなんですけども、配列string の中身の値をdefineによって指定しているのですが、片方のdefineの値を変更する時、もう一つのdefineも手動で変更しています。関係するファイル数が多くなってくると大変なので、どれかのdefineの値を変化させたら自動的に他のdefineの値も変更するプログラムの組み方はありませんか? 質問がわかりにくいかも知れませんがよろしくお願いします。

  • C言語、単語ごとに改行したい

    英文を入力させ、その英文から単語を抜き取るプログラム たとえば、 入力文字:This is a book. 単語: This is a book スペース、カンマ、コロンの時に改行という感じで、このようなプログラムを作りたいのですが、どのような感じに書けばいいでしょうか? わかる方、よろしくおねがいします

  • 分割コンパイルの方法がわかりません‥(Studio.NET)

    mainとsubという2つのcppファイルと各ヘッダファイルで分割コンパイルを試みましたがうまくいきません・・。 何が間違っているのでしょう・・。 エラーメッセージ error LNK2005: "char * a" (?a@@3PADA)は既にmain.objで定義されています。 fatal error LNK1169: 1つ以上の複数回定義されているシンボルが見つかりました。 と表示されます。ファイルソースは以下です。どなたか教えてください>< ----------(main.h)---------- char a[100]; ----------(main.cpp)---------- #include<stdio.h> #include "main.h" #include "sub.h" int main(){  sprintf(a,"hello.");  sub_write();  return 0; } -----------(sub.h)----------- void sub_write(); -----------(sub.cpp)------------- #include <stdio.h> #include "main.h" #include "sub.h" void sab(){  printf("%s\n",a); } return; }

  • TeXで文書作成しているのですが、

    TeXで文書作成しているのですが、 #include <stdio.h> main() { } のプログラムを、 ―――――――――― |#include<stdio.h>  |  |main()          | |{             |  |}             |  ―――――――――― のように、四角の枠で囲むにはどうすればいいでしょうか?

  • 分割コンパイルについて

    現在分割コンパイルが分からずに苦戦しています。 下記のリストは構造体を使わなければコンパイラを通すことができましたが、 使うとなぜか通りません。 あれこれ試しましたがどうしても分かりません。 何がおかしいのでしょうか? *define.hで全てのファイルへの定義や宣言を行わせています。 ////////////// //Main.cpp ////////////// #include <stdio.h> #include <conio.h> #include "define.h" int main( void ){ Tmp[0].c = 15; printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); aaa(); bbb(); getch(); return 0; } ////////////////// // A.cpp ///////////////// #include <stdio.h> #include "define.h" void aaa( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // B.cpp ///////////////// #include <stdio.h> #include "define.h" void bbb( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // define.cpp ///////////////// #include "define.h" int a = 10; int b = 20; struct Parameter { int c; }; struct Parameter Tmp[NUM]; ////////////////// // define.h ///////////////// #define NUM 100 extern int a; extern int b; extern struct Parameter Tmp[NUM]; void aaa( void ); void bbb( void );

  • メモリ確保の謎。

    C言語のメモリの確保の所でふと疑問に思ったのですが、 malloc,calloc,realloc,memset,memcpyなどの関数を使うときって #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <malloc.h> とか書かないといけないと本にはありますが、#include <stdio.h>だけで なんのエラーにもならずに実行できてしまうのはなぜでしょうか? 実際のプログラムにはmallocとreallocしか使ってないのですが、#include <stdio.h>でできてしまいます。 でも教科書には他にも書かなきゃいけないとかいてありますが、なぜ書かなくても実行できてしまうのでしょうか?

専門家に質問してみよう