2016-05-15 12 views
1

私は完全なC++の初心者です。この知識の種類は、私が学ぼうとした他の言語に由来しています。以下のコードはビルドしようとしているモールス・コード・トランスレータの関数ですが、これを "良い方法"に近づけていないと確信しています。私の質問は、ユーザーが入力した文字列をプログラムがどのように見せて、文字の各出現をモールスに変えるのですか?文字列の文字の出現をチェックする方法は?

string ReplaceAll(std::string str, const std::string& from, const std::string& to){ 
size_t start_pos = 0; 
while ((start_pos = str.find(from, start_pos)) != std::string::npos) { 
    str.replace(start_pos, from.length(), to); 
    start_pos += to.length(); // Handles case where 'to' is a substring of 'from' 
} 
return str;} 


void Translate(string s) { 
static string s2 = ReplaceAll(string(s), std::string("a"), std::string(".- ")); 
static string s3 = ReplaceAll(string(s2), std::string("b"), std::string("-... ")); 
static string s4 = ReplaceAll(string(s3), std::string("c"), std::string("-.-. ")); 
static string s5 = ReplaceAll(string(s4), std::string("d"), std::string("-.. ")); 
static string s6 = ReplaceAll(string(s5), std::string("e"), std::string(". ")); 
static string s7 = ReplaceAll(string(s6), std::string("f"), std::string("..-. ")); 
static string s8 = ReplaceAll(string(s7), std::string("g"), std::string("--. ")); 
static string s9 = ReplaceAll(string(s8), std::string("h"), std::string(".... ")); 
static string s10 = ReplaceAll(string(s9), std::string("i"), std::string(".. ")); 
static string s11 = ReplaceAll(string(s10), std::string("j"), std::string(".--- ")); 
static string s12 = ReplaceAll(string(s11), std::string("k"), std::string("-.- ")); 
static string s13 = ReplaceAll(string(s12), std::string("l"), std::string(".-.. ")); 
static string s14 = ReplaceAll(string(s13), std::string("m"), std::string("-- ")); 
static string s15 = ReplaceAll(string(s14), std::string("n"), std::string("-. ")); 
static string s16 = ReplaceAll(string(s15), std::string("o"), std::string("--- ")); 
static string s17 = ReplaceAll(string(s16), std::string("p"), std::string(".--. ")); 
static string s18 = ReplaceAll(string(s17), std::string("q"), std::string("--.- ")); 
static string s19 = ReplaceAll(string(s18), std::string("r"), std::string(".-. ")); 
static string s20 = ReplaceAll(string(s19), std::string("s"), std::string("... ")); 
static string s21 = ReplaceAll(string(s20), std::string("t"), std::string("- ")); 
static string s22 = ReplaceAll(string(s21), std::string("u"), std::string("..- ")); 
static string s23 = ReplaceAll(string(s22), std::string("v"), std::string("...- ")); 
static string s24 = ReplaceAll(string(s23), std::string("w"), std::string(".-- ")); 
static string s25 = ReplaceAll(string(s24), std::string("x"), std::string("-..- ")); 
static string s26 = ReplaceAll(string(s25), std::string("y"), std::string("-.-- ")); 
static string s27 = ReplaceAll(string(s26), std::string("z"), std::string("--.. ")); 

cout << s27 << endl; 

}

+5

文字をモールスコード表現にマップする文字と文字列のマップを作成します。何らかのバッファを作成します。 'std :: stringstream'です。入力内の文字を繰り返し、各文字について、マップ内でそれを調べて、対応する値をバッファに書き込みます。あなたはバッファで何をしたいのですか?それを文字列に変換して印刷してください。 – Biffen

+1

これを行うには、むしろ 'std :: map 'を使いたいと思うでしょう。 –

答えて

0

これは間違ったアプローチです。代わりに、文字列の内容を置き換えるしようとする、それは単純に新しい文字列を作成するためにはるかに簡単です:あなたは非常に簡単で

const char *Translate(char c) 

すべてそれがないことを書くことができ、今

std::string TranslateAll(const std::string &s) 
{ 
    std::ostringstream o; 

    for (char c:s) 
     o << Translate(c); 

    return o.str(); 
} 

は取るです単一の文字をパラメータとして返し、単純な文字列としてそのモールスコードを返します。

はるかに簡単です。

+0

なぜ 'ostringstream'は' string'だけではないのですか? – Qwertiy

2

置換えを使用してstd::mapを作成し、すべての文字を調べて新しい文字列を作成することをお勧めします。あなたの解決文字は.のように-!になります。

#include <iostream> 
#include <map> 

typedef std::map<char, const char*> Replacements; 

std::string Translate(const Replacements& r, std::string s) 
{ 
    std::string result; 
    result.reserve(s.size() * 5); // optional: reserve guessed number of elements for new string 

    // for every element of the string 
    for (char c : s) 
    { 
     // search for replacement 
     Replacements::const_iterator iter = r.find(c); 
     if (iter != r.end()) 
     { 
      // found replacement 
      result += iter->second; 
      result.push_back(' '); 
     }  
    } 

    return result; 
} 


int main() 
{ 
    Replacements morse_code; 
    morse_code['a'] = ".-"; 
    morse_code['b'] = "-..."; 
    morse_code['c'] = "-.-."; 
    // ... 

    std::string in; 
    if (std::cin >> in) 
     std::cout << Translate(morse_code, in) << '\n'; 
} 
+0

ほぼ完璧ですが、私は 'typedef'の代わりに' using'を使い、 'Replacements :: const_iterator'の代わりに' auto'を使い、 'char const *'要素の型を控えるでしょう。なぜ 'std :: string'ではないのですか? –

+0

'auto'と' using'はC++ 11が必要です。 'std :: string'は必要ない割り当てを行います。 – R1tschY

+0

すでに範囲ベースの 'for'ループを使用しています。これにはC++ 11も必要です。 'std :: string'は、内容が十分に短くSSOが使用されている(割り当てられていても、そのような小さなデータには関係ありません)場合、割り当てを行いません。また、文字列リテラルを割り当てたいとは限りませんが、例えば、 'morse_code ['a'] = {dot、minus};'のようにして、 'dot'と' minus'をchar定数として、モールス符号。 –

関連する問題