문제

나는 여러 가지 데이터는 다음과 같습니다.

Vector1_elements = T,C,A
Vector2_elements = C,G,A
Vector3_elements = C,G,T
..... up to ...
VectorK_elements = ...

#Note also that the member of each vector is always 3.

내가 무엇을 원하는지를 만들의 모든 요소의 조합에서 Vector1 을 통해 VectorK.따라서 결국에 우리는 희망이 출력(사용 Vector1,2,3):

TCC
TCG
TCT
TGC
TGG
TGT
TAC
TAG
TAT
CCC
CCG
CCT
CGC
CGG
CGT
CAC
CAG
CAT
ACC
ACG
ACT
AGC
AGG
AGT
AAC
AAG
AAT

문제는 나는 지금은 다음 코드는 내가 그로 하드코딩합니다.이 번호는 벡터의 수는,다양한 우리에게 필요한 가동 가능한 방법으로 동일한 결과입니다.가?

이 코드의 내만을 처리할 수 있는 최대 3 벡터(를):

#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;


int main  ( int arg_count, char *arg_vec[] ) {

    vector <string> Vec1;
          Vec1.push_back("T");
          Vec1.push_back("C");
          Vec1.push_back("A");

    vector <string> Vec2;
          Vec2.push_back("C");
          Vec2.push_back("G");
          Vec2.push_back("A");

    vector <string> Vec3;
          Vec3.push_back("C");
          Vec3.push_back("G");
          Vec3.push_back("T");



     for (int i=0; i<Vec1.size(); i++) {
        for (int j=0; j<Vec2.size(); j++) {
            for (int k=0; k<Vec1.size(); k++) {
                cout << Vec1[i] << Vec2[i] << Vec3[k] << endl;
            }
        }
     }



    return 0;
}
도움이 되었습니까?

해결책

이 될 것이:

void printAll(const vector<vector<string> > &allVecs, size_t vecIndex, string strSoFar)
{
    if (vecIndex >= allVecs.size())
    {
        cout << strSoFar << endl;
        return;
    }
    for (size_t i=0; i<allVecs[vecIndex].size(); i++)
        printAll(allVecs, vecIndex+1, strSoFar+allVecs[vecIndex][i]);
}

전화:

printAll(allVecs, 0, "");

다른 팁

을 구현할 수 있습니다 이 같은 거리에 이르는 다음과(작품에 대한 서로 다른 크기의 벡터):

말이 있 K 벡터 배열에서 v: v[0], v[1], ... v[K-1]

유지 배열을 반복기 it (size K)으로 귀하의 벡터 시작으로, it[i] = v[i].begin().계속 증가 it[K-1] 에 있습니다.어떤 때는 반복기타 end() 의 해당하는 벡터,당신은 당신 주위를 감싸기 begin() 그리고 증가는 이전의 반복기도(그래서 때 it[K-1] 주위를 감싸는,당신은 증가 it[K-2]).이러한 증가할 수 있"캐스케이드"그렇게 당신이 해야 할 루프에서 뒤에 있다.면 it[0] 주위를 감싸는,당신은(그래서 루프 조건실 수 있습니다 while (it[0] != v[0].end())

모두는 함께하는 루프가 작업(설정한 후에는 반복기)의는 다음과 같습니다:

while (it[0] != v[0].end()) {
  // process the pointed-to elements

  // the following increments the "odometer" by 1
  ++it[K-1];
  for (int i = K-1; (i > 0) && (it[i] == v[i].end()); --i) {
    it[i] = v[i].begin();
    ++it[i-1];
    }
  }

당신이 관심이 있다면 점점 더 복잡해짐에 따라 번호 반복기의 증가를 얻을 수행이 계산하기 쉽습니다.단순화를 위해 여기에서 내가 가정의 각터 같은 길이 N.총 숫자의 조합 NK.지난 반복기를 얻할 때마다 증가하는,그래서 그 NK, 며,이를 통해 반복기를 이 개수에 의해 분할 N 때마다,그래서 우리는 NK +NK-1 +...N1;이 합 N(NK -1)/(N-1)=O(NK).이것은 또한 분할 상환당 비용-조합은 O(1).

어쨌든 짧은 치료계 회전시키는 그 자리 바퀴가 있습니다.

C++0x 솔루션입니다.제공은 물론,컴파일된 지원(현재 GCC4.5 및 VS2010,나는 생각한다).

다음과 같은 컴파일하고 GCC4.5 사용 -std=c++0x 스위치입니다.용의 앞을 가능하게 결합 임의의 숫자의 용기입니다.나는 확신할 수 있습으로 올 더 많은 관용적 솔루션입니다.

#include <vector>       
#include <string>
#include <sstream>
#include <iostream>
#include <algorithm>

typedef std::vector<std::string> myvec;

// Base case.
void combine2(const std::string &row) {
    std::cout << row << std::endl;
}

// Recursive variadic template core function.
template<class T0, class ...T>
void combine2(const std::string &row, const T0& cont0, T...cont_rest) {
    for (auto i = cont0.begin(); i != cont0.end(); ++i) {
        std::stringstream ss;
        ss << row << *i;
        combine2(ss.str(), cont_rest...);
    }
}

// The actual function to call.
template<class ...T>
void combine(T...containers) {
    combine2("", containers...);
}

int main() {
    myvec v1 = {"T", "C", "A"}, v2 = {"C", "G", "A"}, v3 = {"C", "G", "T"};

    combine(v1);
    combine(v1, v2);
    combine(v1, v2, v3);

    // Or even...
    std::vector<std::string> v4 = {"T", "C", "A"};
    std::vector<char> v5 = {'C', 'G', 'A'};
    std::vector<int> v6 = {1 ,2 ,3};

    combine(v4);
    combine(v4, v5);
    combine(v4, v5, v6);

    return 0;
}

기본적인 어려움과 재귀 여기에 당신을 추적해야의 전체 목록 지수(또는 다른 문자열을 구성 증대로,다른 질문은 점).

편법을 처리하는 방법이 이 문제없이 생성 개체를 추가로 내부 반복하는 손으로 당신의 재귀적 기능의 벡터가 지수,의와 같은 길이 벡터의 벡터:

void printcombos(const vector<vector<string> >&vec,vector<int>&index,int depth) {
  if(depth==index.length()) {
    for(int i=0; i<depth; ++i) {
      cout<<vec[i][index[i]];
    }
    cout<<endl;
  } else {
    const vector<string> &myvec= vec[depth];
    int mylength= myvec.length();
    for(int i=0; i<mylength; ++i) {
      index[depth]=i;
      printcombos(vec,index,depth+1);
    }
  }
}

과 벡터의 본질적으로 같은 처음 두 가지의 결합 벡터,다음 결합하는 세 번째 중 하나로 결과입니다.

그래서 그것을 모두 아래로 쓰기 기능이 결합할 수 있는 두 개의 벡터입니다.

std::vector< std::string > combine(std::vector< std::string > const & inLhs, std::vector< std::string > const & inRhs) {
    std::vector< std::string > result;
    for (int i=0; i < inLhs.size(); ++i) {
        for (int j=0; j < inRhs.size(); ++j) {
            result.push_back(inLhs[i] + inRhs[j]);
        }
    }
    return result;
}

다음 같은 것:

std::vector< std::string > result = combine(Vec1, Vec2);
result = combine(result, Vec3);

그래서에 대한 모든 벡터 당신은 필요합니다.

참고하는 것이 더"C++"방법을 사용하여 입력 및 출력 반복기를 내가.s.o.전달하는 벡터의 주위에,그리고 훨씬 더 효율적입니다.에서 이상 버전에서 벡터로 복사되고...

나는 단순히 사용되는 벡터가 숙박 시설에 가까운의 원래 코드를 그리고,잘하면,더 이해 당신입니다.

때문에 당신이 원하는 것을 보 각 출력 될 길이의 개별 벡터,당신은 알고 보이는 각각의 벡터는 3 요소의 넓은에서

#Note also that the member of each vector is always 3.

재귀를 이용한 일반적인 솔루션을 보 과잉 여기에.

당신이 사용할 수 있는 그런 것 같:

typedef boost::array<std::string, 3> StrVec;
// basically your hardcoded version corrected (Vec2[j] not [i])
void printCombinations(const StrVec &Vec1,
                       const StrVec &Vec2,
                       const StrVec &Vec3) {
    for (int i=0; i<Vec1.size(); i++) {
        for (int j=0; j<Vec2.size(); j++) {
            for (int k=0; k<Vec3.size(); k++) {
                std::cout << Vec1[i] << Vec2[j] << Vec3[k] << std::endl;
            }
        }
    }
}

void foo() {
    typedef std::vector<StrVec> StrVecLvl2;
    StrVecLvl2 vecs;

    // do whatever with it ...

    // iterate with index instead of iterator only to shorten the code
    for (int i = 0; i < vecs.size(); ++i) {
        for (int j = i+1; j < vecs.size(); ++j) {
            for (int k = j+1; k < vecs.size(); ++k) {
                printCombinations(vecs[i], vecs[j], vecs[k]);
            }
        }
    }
}

나도 이 건물에 관심있는 몇 가지 종류의 쉽게 씻어내고 반복의 조합.나 익숙한 거리계동 유형 접근 방식을,당신이 경우에,당신은 도보 인덱스입니다.합니다.지점을 쉽게 구축 튜플에서 임의로 설정의 관련이 없는 벡터입니다.

이지 않는 아주 당신의 질문에 대답,나는 생각하지 않지만,작성할 수 있는 정적/설계 시간을 조합을 사용하여 생산됩니 다음과 같은 곳,T1-3 은 임의의 유형:

template<class V>
void push_back_tupled_combos(V& v) {
  // Variadic no-args no-op
}

template<class V, typename A, typename B, typename C, typename... Args>
void push_back_tupled_combos(V& v, A a, B b, C c, Args... args) {
    v.push_back({ a, b, c });
    push_back_tupled_combos(v, args...);
}

template<class V, typename... Args>
void push_back_tupled_combos(V& v, Args... args) {
}

고 가정하고 당신은 벡터는 다음과 같이 나타납니다.

typedef vector<tuple<T1, T2, T3>> CombosVector;

CombosVector combos;

push_back_tupled_combos(combos
  , 1, 2, 3
  , 4, 5, 6
  , 7, 8, 9, ...);

내가 말했듯이,이은 디자인 시 고려 사항입니다.그것을 구축하지 않는 튜플에 걸쳐 실행 시간의 범위를 벡터입니다.는 아닙니다.호조를 보이기 시작하는,그러나,당신이 컴파일간의 이해력의 벡터화 튜플이 있습니다.

다시지 않습니다,당신이 무엇을,또는 나은 후,하지만 어쩌면 그것은 불꽃을 호의를 베푸는 의견을.

위 printAll 솔루션을 벡터의 동일한 크기입니다.

고정하는 문제점:

 void printAll(const vector<vector<string> > &allVecs, size_t vecIndex, string strSoFar)
{
    if (vecIndex >= allVecs.size())
    {
        cout << strSoFar << endl;
        return;
    }

    for (size_t i = 0; i < allVecs[vecIndex].size(); i++)
    {
        if( i < allVecs[vecIndex].size() )
        {
            printAll(allVecs, vecIndex + 1, strSoFar + " " + allVecs[vecIndex][i]);
        }
    }
}

int main()
{
    vector <string> Vec1;
    Vec1.push_back("A1");
    Vec1.push_back("A2");
    Vec1.push_back("A3");
    Vec1.push_back("A4");

    vector <string> Vec2;
    Vec2.push_back("B1");
    Vec2.push_back("B2");

    vector <string> Vec3;
    Vec3.push_back("C1");

    vector<vector<string> > allVecs;
    allVecs.push_back(Vec3);
    allVecs.push_back(Vec1);
    allVecs.push_back(Vec2);

    printAll(allVecs, 0, "");
}

가장 간단한 방법이 사용하는 재귀.함수해야 하는 루프에서 호출 자체를 병합체 출력적화.물론,재귀로 변환할 수 있습을 반복 걱정이라면 공지만,최소한 출발점으로,재귀적 솔루션을 것입니다 아마 당신을 위해 가장 쉬운 방법.

사용 next_permutation 기능 구현에 std 의 stl

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top