2016-08-08 11 views
0

私はstd :: async(またはstd :: thread)インプレースを使用して文字列を反転しようとしていますが、正常なアルゴリズムを見つけることができませんでした。簡単にするためstd :: asyncを使用してインプレース文字列を逆順

void reverse(char* x, char* y) 
{ 
    while (x < y) 
    { 
     char temp = *x; 
     *x = *y; 
     *y = temp; 
     x++; 
     y--; 
    } 
} 

int main(int argc, char** argv) 
{ 
    int numthreads = 2; 
    char input[] = "abcdef"; 
    size_t size = strlen(input); 
    size_t substrsize = 0; 

    substrsize = size/numthreads; 

    char* end = &input[strlen(input) - 1]; 
    char* begin = &(input[size-substrsize]); 

    for (int i = 0; i < numthreads; i++) 
    { 
     std::async(std::launch::async, reverse, begin, end); 
     end = begin -1; 
     begin = begin-substrsize; 
    } 

    cout << input << endl;  
    return 0; 
} 

、Iは、入力が等しい大きさのサブストリングに分割することができると仮定している(すなわち、サイズ%NumThreadsにはゼロとする)

をしかし、上記で、Iは出力に何を得ます次のとおりです。

cbafed 

この出力は、abcとdefが逆転しているためわかります。しかし、正しい出力はfedcbaになります。

希望の出力を得るためにこのコードを拡張することはできますか?返された未来をベクトルで(移動して)保存してから呼び出すようにしましたが、役に立たなかった(おそらく関数がvoidを返すため)。

正しく動作させるためにヒントや示唆を与えてください。 多くの感謝!

+0

非同期なしで試しましたか? – GManNickG

+0

@ GManNickG std :: threadの配列を試しましたが、同じ結果が得られます。 – user2930006

+2

私は、彼がスレッドをチャックして、あなたのコードが逐次実行されるのを見ることを意味すると思う。さらに、「デバッガでコードを実行し、スレッドなしで動作するまでコードを微調整してください。いったん動作したら、スレッドを追加して、スレッドが同時にmutexやその他のものを追加するまで破壊を防ぐように。 – user4581301

答えて

0

アルゴリズムは、ソース文字列を2つの部分文字列に分割します。最初の部分文字列は "def"です。あなたの "逆"アルゴリズムは "d"と "f"を交換し、ポインタは "e"を指すように指示し、 "e"はそれ自身と入れ替えます。

結果は、2つの逆の部分文字列である:

void reverse(char* begin, const char* const end, char* back) { 
    while (begin != end) { 
     std::swap(*(begin++), *(--back)); 
    } 
} 

そして、あなたが必要とする:

abc def 

あなたは3つの入力を取るために、あなたの逆のアルゴリズムを変更する必要が

cba fed 

なり文字列の部分範囲で呼び出す:

size_t subtrlen = 2; 
reverse(input + 0, input + substrlen, input + sizeof(input) - 1); 
reverse(input + substrlen, input + 3, input + sizeof(input) - 1 - substrlen); 

デモ:

#include <iostream> 
#include <string.h> 

void reverse(char* begin, const char* const end, char* back) { 
    while (begin != end) { 
     std::swap(*(begin++), *(--back)); 
    } 
} 

int main(int argc, char** argv) 
{ 
    char input[] = "abcdef"; 
    size_t len = strlen(input); 
    size_t substrlen = 2; 
    std::cout << input << std::endl;  
    reverse(input, input + substrlen, input + len); 
    reverse(input + substrlen, input + substrlen, input + len - substrlen); 
    std::cout << input << std::endl; 
    return 0; 
} 

http://ideone.com/gGjB9D

-1

私は間違っていないよ場合は、文字列にマルチスレッドの道を逆にしようとしています。したがって、マルチスレッドのコンテキストで実行するアルゴリズムが必要です。

これは私があなたに提案できる簡単な解決策です。

アルゴリズム(funciton)マルチスレッドは

void reverse_str_mt(char* str, 
       const size_t len, 
       const size_t id_thread, 
       const size_t max_num_threads) { 
    // Some assertion on input parameters 
    assert(str != nullptr); 
    assert(max_num_threads != 0); 

    // In case the num of threads is greater than the len of the string 
    if (id_thread > len) { 
    assert(max_num_threads > len); 
    return; 
    } 

    // Swap operation 
    for (size_t i = id_thread; i <= len/2; i += max_num_threads) { 
    std::swap(str[i], str[len - i - 1]); 
    } 
} 

であり、あなたがこの方法のような文字列を操作することができます

int main(int argc, char *argv[]) { 
    static constexpr size_t NUM_THREADS = 10; 
    char str[] = "123456"; 
    const auto len = strlen(str); 

    std::vector<std::thread> threads; 
    for (size_t i = 0; i < NUM_THREADS; ++i) { 
    threads.emplace_back(reverse_str_mt, str, len , i, NUM_THREADS); 
    } 

    // Join threads 
    for (auto& t : threads) { 
    t.join(); 
    } 

    // Print the result 
    std::cout << str << std::endl; 

    return 0; 
} 

ただ、完全を期すためにあなたが含まれている必要があり、ヘッダーは次のとおりです。

#include <iostream> 
#include <algorithm> 
#include <vector> 
#include <string> 
#include <thread> 
#include <cstring> 
#include <cassert> 

これは実行可能なexampleです。

+0

はい、私はマルチスレッドを使用して逆を探していました。私の最初の投稿の後、私は非同期を使用してそれを行うことができましたが、効率的ではない逆の各部分文字列のコピーを作成しなければなりませんでした。ちょっと考えれば、forループなしでスワップすることができます: 'if(id_thread user2930006

+0

@ user2930006 * forループ*が必要です。スレッドの数が文字列の長さよりも大きい場合にのみ、ソリューションが機能します。 –

関連する問題