如何根据字符位置重新排序字符串

时间:2017-11-04 15:18:14

标签: arrays ruby string loops

我正在努力定义一个能够转换字符串的方法,如:

#include <iostream>
#include <utility>

template <size_t N>
struct bits {
    bool bs[N];

    template <size_t I>
    constexpr const bool& bit() const {
        return bs[I];
    }
    template <size_t I>
    constexpr bool& bit() {
        return bs[I];
    }

    constexpr bool bit(int i) const { return bs[i]; }
    constexpr void bit(int i, bool x) { bs[i] = x; }
};

// Using C++17 fold expressions

template <size_t N, size_t... Is>
constexpr bits<N> set_bits_helper(bits<N> x, std::index_sequence<Is...>) {
    ((x.bit<Is + 2>() = x.bit<Is>()), ...);
    return x;
}

template <size_t N>
constexpr bits<N> set_bits(bits<N> x) {
    return set_bits_helper(x, std::make_index_sequence<N - 2>{});
}

// Using recursive template function, should work on C++11

template <size_t I, size_t N>
constexpr bits<N> set_bits_recursive_helper(bits<N> x, std::integral_constant<size_t, I>) {
    x.bit<N - I>() = x.bit<N - I - 2>();
    return set_bits_recursive_helper(x, std::integral_constant<size_t, I - 1>{});
}

template <size_t N>
constexpr bits<N> set_bits_recursive_helper(bits<N> x, std::integral_constant<size_t, 0>) { return x; }

template <size_t N>
constexpr bits<N> set_bits_recursive(bits<N> x) {
    return set_bits_recursive_helper(x, std::integral_constant<size_t, N - 2>{});
}

// Using non template constexpr functions
template <size_t N>
constexpr bits<N> set_bits_constexpr(bits<N> x) {
    for (int i = 0; i < N - 2; ++i) {
        x.bit(i + 2, x.bit(i));
    }
    return x;
}

// Test code to show usage

template <size_t N>
void print_bits(const bits<N>& x) {
    for (auto b : x.bs) {
        std::cout << b << ", ";
    }
    std::cout << '\n';
}

void test_set_bits() {
    constexpr bits<8> x{ 1, 0 };
    print_bits(x);
    constexpr auto y = set_bits(x);
    static_assert(y.bit<2>() == x.bit<0>());
    print_bits(y);
}

void test_set_bits_recursive() {
    constexpr bits<8> x{ 1, 0 };
    print_bits(x);
    constexpr auto y = set_bits_recursive(x);
    static_assert(y.bit<2>() == x.bit<0>());
    print_bits(y);
}

void test_set_bits_constexpr() {
    constexpr bits<8> x{ 1, 0 };
    print_bits(x);
    constexpr auto y = set_bits_constexpr(x);
    static_assert(y.bit<2>() == x.bit<0>());
    print_bits(y);
}

int main() {
    test_set_bits();
    test_set_bits_recursive();
    test_set_bits_constexpr();
}

成:

"abcd\nefgh\nijkl\nmnop"

我有一个漫长的过程,但我确信我可以通过一个循环倒计时迭代:

"plhd\nokgc\nnjfb\nmiea"

欢迎任何帮助。谢谢!

1 个答案:

答案 0 :(得分:2)

str = "abcd\nefgh\nijkl\nmnop"
str.split("\n").map(&:chars).transpose.map{ |x| x.join.reverse }.reverse.join("\n")
#=>  "plhd\nokgc\nnjfb\nmiea"

说明:

str.split("\n") # breaks into parts
#=> ["abcd", "efgh", "ijkl", "mnop"]
str.split("\n").map(&:chars) #converts each part into individual char group
#=> [["a", "b", "c", "d"], ["e", "f", "g", "h"], ["i", "j", "k", "l"], ["m", "n", "o", "p"]]
str.split("\n").map(&:chars).transpose # transpose the array - groups by position
#=> [["a", "e", "i", "m"], ["b", "f", "j", "n"], ["c", "g", "k", "o"], ["d", "h", "l", "p"]]
str.split("\n").map(&:chars).transpose.map{ |x| x.join.reverse } # joins back each group and reverses
#=> ["miea", "njfb", "okgc", "plhd"]
str.split("\n").map(&:chars).transpose.map{ |x| x.join.reverse }.reverse #reverse entire group
#=> ["plhd", "okgc", "njfb", "miea"]
str.split("\n").map(&:chars).transpose.map{ |x| x.join.reverse }.reverse.join("\n") # joins back
#=> "plhd\nokgc\nnjfb\nmiea"

事实上,您可以在原始字符串上执行一次反向操作,而不是在以后反转每个组:

str = "abcd\nefgh\nijkl\nmnop"
str.reverse.split("\n").map(&:chars).transpose.map(&:join).join("\n")