ページ 11

言葉遊びのプログラムのプログラミングを助けて下さい!

Posted: 2014年10月13日(月) 04:06
by star
Pig Latin という英語の言葉遊びのプログラミングがどうにも上手く行きません。

このプログラムでは例えば'jump'を'umpjay'の様に英単語の最初のアルファベットを後ろに入れ替えて、その後ろにayと付け加えたいのですが、入れ替えと追加のコードの書き方がさっぱりです。
switch と voidを使うように言われていますが全く動く気配がしません。

アドバイスを頂けるとありがたいです。

コード:

#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;

string newstring(string);
bool isVowel(char ch);
string rotate(string pStr);
string pigLatinString(string pStr);


int main()
{
	string str;

	cout << "Please enter a word: ";
	getline (cin, str);
	cout << endl;

	cout << "The pig latin for " << str << "is" << newstring(str) << "ay";
	
	system ("PAUSE");
	return 0;
}

Re: 言葉遊びのプログラムのプログラミングを助けて下さい!

Posted: 2014年10月13日(月) 10:05
by sleep
starさんが欲しいのは答えではなくて、アドバイスですよね。
皆さんに教えていただく前に、もう少しルールを明確に提示してあげると良いかもしれません。

例えば、Pig Latinは以下のルールに従うこととする。
・英単語の頭文字が母音の場合、頭文字をrotateしない。 (october ⇒ october)
・英単語の頭文字が子音の場合、頭文字をrotateする。 (jump ⇒ umpj)
・上記後の英単語の末尾に ay を追加する。 (umpj ⇒ umpjay, october ⇒ octoberay)
・Y* は「基本的に」単語や音節の最初の文字になった時は子音となるので、今回は全て子音として扱うこと。

母音
A, E, I, O, U, Y*

子音
B, C, D, F, G, H, J, K, L, M, N, P, Q, R, S, T, V, W, X, Y*, Z


アドバイスは以下です。
・switchは、頭文字が母音である場合とそれ以外の場合を判定するために使用できそうです。
・voidは、必要ない気がします。(何に使うのでしょうね?)
・rotateは、標準関数のstd::rotate()を使用して問題ないと思います。
オフトピック
PAUSE を使用されているので、Windows環境ですよね。
もし、アルファベットかどうかの判定をする場合は以下に気を付けてください。

VisualStudioの場合、isalpha()は
・Debug環境では、charが(char >= -1 && char <= 255)に納まっていないと例外が発生します。
・Release環境では、例外は発生しません。

以下のようにするとDebug環境でも例外を回避することができます。

コード:

auto initials = toupper(str[0]);
if (initials >= 'A' && initials <= 'Z')
{
	//アルファベットだった場合の処理を記述する
}
私からアドバイスできそうなのはこんなところです。

Re: 言葉遊びのプログラムのプログラミングを助けて下さい!

Posted: 2014年10月13日(月) 21:45
by star
アドバイスありがとうございます。
おっっしゃる通り、アドバイスが欲しいのです。

問題の正確なルールでは
例えば、Pig Latinは以下のルールに従うこととする。
・英単語の頭文字が母音でも子音の場合、頭文字をrotateする。(october ⇒ ctobero) (jump ⇒ umpj)
・上記後の英単語の末尾に ay を追加する。 (umpj ⇒ umpjay, ctobero ⇒ ctoberoay)
`そして最終的には文書レベルでrotate 出来るようにしたいです。 
(Oh my god ⇒ hOay ymay odgay)

コードの添付ありがとうございます。

Re: 言葉遊びのプログラムのプログラミングを助けて下さい!

Posted: 2014年10月17日(金) 22:11
by かずま
次の手順でよいでしょう。
・文字列を先頭から順番に最後まで見ていく
 ・英字でなければ、そのまま出力
 ・英字だったら、その文字を覚えておき、
  ・後続の英字が続く限り、それらをそのまま出力
  ・憶えておいた単語の先頭文字と "ay" を出力

無理やり switch と void を使うと、

コード:

#include <iostream>  // cout 
#include <string>    // string
#include <cctype>    // isalpha 

using namespace std;

void pig_latin(const string& s)
{
    unsigned char c, c2;
    size_t n = s.size();
    for (size_t i = 0; i < n; )
        switch (isalpha(c = s[i++])) {
        case 0: 
            cout << c;
            break;  
        default:
            for (; i < n && isalpha(c2 = s[i]); i++)
                cout << c2;
            cout << c << "ay";
        }
}
コードが理解できたら、自分流に書き直し、これを呼び出す
main を加えて提示し、解決としてください。
理解できなかったら、わからないところを質問してください。